Oracle解析复杂json的方法
admin
2023-05-22 08:03:00
0

当前在Oracle数据库(11G之前的版本)解析json没有可以直接使用的系统方法,网上流传的PLSQL脚本大多也只可以解析结构较单一的json串,对于结构复杂的json串还无法解析。如此一来导致即便可以在PL/SQL中调用远程接口,但返回结果仍需传给前台js或java等其它代码进行处理,不太方便。

分析思路:

         1、在PL/SQL中写json串,无需声明json对象,只需直接拼接成格式正确的json字符串即可,因此数据库对象间json串的传递完全可以用varchar2或clob来代替。

         2、结构复杂的json串节点元素值基本上可以分为两类:①仍为json串②json数组,因此我们只需对这两种类型的json对象进行处理即可。

         3、在PL/SQL中处理json数组时,由于json元素是无序且可以重复的,因此我们需要对数组成员进行索引并能够获取数组长度才可以对其循环处理。

         4、java中有很多可以方便解析json串的开源jar包,且数据库支持导入java类文件,因此是否可以将java代码编译生成的class导入数据处理json呢?

解决方案:

方法1:loadjava导入java类进行解析

1、查看当前数据库已导入的java类文件

Oracle解析复杂json的方法

2、执行loadjava命令导入处理json所需jar文件,在此选择org.json而不选择fastjson或jackson的原因是该jar包没有外部依赖且满足功能的同时所需导入类文件较少。

--向数据库导入json相关jar包loadjava -r   -f  -u  scott/tiger@xxx.xxx.xxx.xxx:1521/orcl json.jar--删除指定jar#dropjava -u scott/tiger@xxx.xxx.xxx.xxx:1521/orcl json.jar

在此,我们执行导入,如下:

 Oracle解析复杂json的方法

细节:如果导入的jar包存在外部依赖,会报如下异常,继续导入外部依赖只会使要导入的jar包越来越多,最终还不一定可以导入成功,得不偿失,如下:

 Oracle解析复杂json的方法

3、导入json.jar成功后再次查看当前已导入的类文件如下

 Oracle解析复杂json的方法

4、在数据库SQL窗口执行以下脚本,创建java源码对象

Oracle解析复杂json的方法

 1 create or replace and compile java source named "JsonUtil" as 2  3 import org.json.JSONArray; 4 import org.json.JSONException; 5 import org.json.JSONObject; 6 import java.lang.Integer; 7  8 public class JsonUtil { 9   10  //取json串单个节点值11   public static String getValue(String jsonStr,String nodeName){12     String nodeValue="";13     try {14       if(jsonStr==null||!jsonStr.startsWith("{")||!jsonStr.endsWith("}")){15         nodeValue="";16       }else{17         JSONObject obj =new JSONObject(jsonStr);18         nodeValue = obj.getString(nodeName);19       }20     } catch (JSONException e) {21       nodeValue="";22     }23     return nodeValue;24   }25   //取json数组长度便于循环处理26   public static Integer getArrayLength(String jsonArrayStr){27     Integer length=0;28     try {29       if(jsonArrayStr==null||!jsonArrayStr.startsWith("[")||!jsonArrayStr.endsWith("]")){30         length=0;31       }else{32         JSONArray jsonArr = new JSONArray(jsonArrayStr);33         length=jsonArr.length();34       }35     } catch (JSONException e) {36       length=0;37     }38     return length;39   }40 41   //取json数组第index个元素42   public static String getArrayValue(String jsonStr,Integer index){43     String nodeValue="";44     try {45       if(jsonStr==null||!jsonStr.startsWith("[")||!jsonStr.endsWith("]")){46         nodeValue="";47       }else{48         JSONArray jsonArr = new JSONArray(jsonStr);49         nodeValue=jsonArr.getString(index);50       }51     } catch (JSONException e) {52       nodeValue="";53     }54     return nodeValue;55   }56 }

Oracle解析复杂json的方法

创建成功后再次查询可以看到对应的class文件:

 Oracle解析复杂json的方法

5、利用步骤4创建的class创建function(或procedure),在此为了使其跟目前数据库已存在的json处理方法区分开,我们创建一个package,如下:

Oracle解析复杂json的方法

 1 create or replace package jsonpkg 2 as 3 function getval(jsonstr varchar2,nodename varchar2) return varchar2; 4 function getarrval(jsonArrayStr varchar2,seqNo number) return varchar2; 5 function getarrlen(jsonArrayStr varchar2) return number; 6 end jsonpkg; 7 / 8 create or replace package body jsonpkg 9 as10 function  getval(jsonstr varchar2,nodename varchar2) return varchar211 as language java name 'JsonUtil.getValue(java.lang.String,java.lang.String) return java.lang.String';12    13 function getarrval(jsonArrayStr varchar2,seqNo number) return varchar214 as language java name 'JsonUtil.getArrayValue(java.lang.String, java.lang.Integer) return java.lang.String';15 16 function getarrlen(jsonArrayStr varchar2) return number17 as language java name 'JsonUtil.getArrayLength(java.lang.String) return java.lang.Integer';18 19 end jsonpkg;20 /

Oracle解析复杂json的方法

创建成功后可以查看包说明和主体:

Oracle解析复杂json的方法

Oracle解析复杂json的方法

6、测试

①简单json测试

 Oracle解析复杂json的方法

Oracle解析复杂json的方法

Oracle解析复杂json的方法

②解析复杂json

 Oracle解析复杂json的方法

至此,我们就可以很轻松的就取到json串中任意节点的值(如果节点值为数组则可以先计算数组长度再进行loop循环处理,或直接用getarrval方法取指定数组元素的值)。

 

方法2:安装开源组件PL/JSON

下载地址: https://github.com/pljson/pljson

 Oracle解析复杂json的方法

优点:安装方便,解析方法较专业;缺点:新增数据库对象较多,短期学习成本较高。文档很详细,在此不再赘述。


相关内容

热门资讯

筑牢数字生命线,科士达以智慧能... 5月17日世界电信和信息社会日,2026 年国际电信联盟(ITU)以 “数字生命线:在互联世界中加强...
特朗普称将推迟对伊朗发动军事打... 当地时间5月18日,美国总统特朗普在社交平台“真实社交”发文表示,在卡塔尔、沙特阿拉伯、阿联酋领导人...
全国首个遥感卫星数据出境安全评... 5 月 18 日消息,据央视新闻今日报道,记者从海南省委网信办获悉,近日,全国首个遥感卫星数据出境安...
波兰防长:得和美国聊聊,不能以... 【文/观察者网 张菁娟】美军突然暂停对波兵力部署后,波兰连连喊话美国,迫切希望美方稳固对其安全承诺。...
世界博物馆日丨我在杭州修文物:... 5月18日,世界博物馆日。 在位于杭州市之江的浙江省博物馆,一场名为“古陶瓷修补装饰技艺展”的展览正...
“四川智造”如何护航天舟十号“... “四川智造”如何护航天舟十号“太空快递”? 2026年5月11日8时14分,搭载天舟十号货运飞船...
被困近11小时,广西柳州地震9... 5月18日,广西柳州市抗震救灾新闻发布会在太阳村镇上等村举行。柳州市消防救援局相关负责人介绍了91岁...
酒钢成功研发食品级瓶盖专用铝材 近日,酒钢突破传统热轧工艺限制,成功研发短流程铸轧薄坯高深冲铝板带——食品级瓶盖专用料,让国产高品质...
和铂医药公布首款AI候选药物L... 来源:上海证券报·中国证券网 和铂医药(股票代码:02142.HK),一家专注于免疫性疾病、肿瘤及其...
从深海孤岛到田间工厂,织就一张... 100%与97.9%,是山东省行政村移动网络覆盖与5G覆盖的双重刻度;全国首张5G全海岸线连续覆盖网...