Oracle解析復雜json的方法實例詳解
問題背景:
當前在Oracle數(shù)據(jù)庫(11G之前的版本)解析json沒有可以直接使用的系統(tǒng)方法,網(wǎng)上流傳的PLSQL腳本大多也只可以解析結構較單一的json串,對于結構復雜的json串還無法解析。如此一來導致即便可以在PL/SQL中調用遠程接口,但返回結果仍需傳給前臺js或java等其它代碼進行處理,不太方便。
分析思路:
1、在PL/SQL中寫json串,無需聲明json對象,只需直接拼接成格式正確的json字符串即可,因此數(shù)據(jù)庫對象間json串的傳遞完全可以用varchar2或clob來代替。
2、結構復雜的json串節(jié)點元素值基本上可以分為兩類:①仍為json串②json數(shù)組,因此我們只需對這兩種類型的json對象進行處理即可。

3、在PL/SQL中處理json數(shù)組時,由于json元素是無序且可以重復的,因此我們需要對數(shù)組成員進行索引并能夠獲取數(shù)組長度才可以對其循環(huán)處理。
4、java中有很多可以方便解析json串的開源jar包,且數(shù)據(jù)庫支持導入java類文件,因此是否可以將java代碼編譯生成的class導入數(shù)據(jù)處理json呢?
解決方案:
方法1:loadjava導入java類進行解析
1、查看當前數(shù)據(jù)庫已導入的java類文件
2、執(zhí)行l(wèi)oadjava命令導入處理json所需jar文件,在此選擇org.json而不選擇fastjson或jackson的原因是該jar包沒有外部依賴且滿足功能的同時所需導入類文件較少。
--向數(shù)據(jù)庫導入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
在此,我們執(zhí)行導入,如下:

細節(jié):如果導入的jar包存在外部依賴,會報如下異常,繼續(xù)導入外部依賴只會使要導入的jar包越來越多,最終還不一定可以導入成功,得不償失,如下:

3、導入json.jar成功后再次查看當前已導入的類文件如下

4、在數(shù)據(jù)庫SQL窗口執(zhí)行以下腳本,創(chuàng)建java源碼對象
create or replace and compile java source named "JsonUtil" as
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.Integer;
public class JsonUtil {
//取json串單個節(jié)點值
public static String getValue(String jsonStr,String nodeName){
String nodeValue="";
try {
if(jsonStr==null||!jsonStr.startsWith("{")||!jsonStr.endsWith("}")){
nodeValue="";
}else{
JSONObject obj =new JSONObject(jsonStr);
nodeValue = obj.getString(nodeName);
}
} catch (JSONException e) {
nodeValue="";
}
return nodeValue;
}
//取json數(shù)組長度便于循環(huán)處理
public static Integer getArrayLength(String jsonArrayStr){
Integer length=0;
try {
if(jsonArrayStr==null||!jsonArrayStr.startsWith("[")||!jsonArrayStr.endsWith("]")){
length=0;
}else{
JSONArray jsonArr = new JSONArray(jsonArrayStr);
length=jsonArr.length();
}
} catch (JSONException e) {
length=0;
}
return length;
}
//取json數(shù)組第index個元素
public static String getArrayValue(String jsonStr,Integer index){
String nodeValue="";
try {
if(jsonStr==null||!jsonStr.startsWith("[")||!jsonStr.endsWith("]")){
nodeValue="";
}else{
JSONArray jsonArr = new JSONArray(jsonStr);
nodeValue=jsonArr.getString(index);
}
} catch (JSONException e) {
nodeValue="";
}
return nodeValue;
}
}
創(chuàng)建成功后再次查詢可以看到對應的class文件:

5、利用步驟4創(chuàng)建的class創(chuàng)建function(或procedure),在此為了使其跟目前數(shù)據(jù)庫已存在的json處理方法區(qū)分開,我們創(chuàng)建一個package,如下:
create or replace package jsonpkg as function getval(jsonstr varchar2,nodename varchar2) return varchar2; function getarrval(jsonArrayStr varchar2,seqNo number) return varchar2; function getarrlen(jsonArrayStr varchar2) return number; end jsonpkg; / create or replace package body jsonpkg as function getval(jsonstr varchar2,nodename varchar2) return varchar2 as language java name 'JsonUtil.getValue(java.lang.String,java.lang.String) return java.lang.String'; function getarrval(jsonArrayStr varchar2,seqNo number) return varchar2 as language java name 'JsonUtil.getArrayValue(java.lang.String, java.lang.Integer) return java.lang.String'; function getarrlen(jsonArrayStr varchar2) return number as language java name 'JsonUtil.getArrayLength(java.lang.String) return java.lang.Integer'; end jsonpkg; /
創(chuàng)建成功后可以查看包說明和主體:


6、測試
①簡單json測試



②解析復雜json

至此,我們就可以很輕松的就取到json串中任意節(jié)點的值(如果節(jié)點值為數(shù)組則可以先計算數(shù)組長度再進行l(wèi)oop循環(huán)處理,或直接用getarrval方法取指定數(shù)組元素的值)。
方法2:安裝開源組件PL/JSON
下載地址: https://github.com/pljson/pljson

優(yōu)點:安裝方便,解析方法較專業(yè);缺點:新增數(shù)據(jù)庫對象較多,短期學習成本較高。文檔很詳細,在此不再贅述。如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關文章
解決Windows 7下安裝Oracle 11g相關問題的方法
本文將為大家介紹Windows 7下安裝Oracle 11g方面的有關問題解決方案。希望通過本文,能讓大家對11g這款產品有更多的認識,需要的朋友可以參考下2015-08-08
oracle11g 通過修改配置文件方式連接遠程數(shù)據(jù)庫的方法
這篇文章主要介紹了oracle11g 通過修改配置文件方式連接遠程數(shù)據(jù)庫的方法,需要的朋友可以參考下2017-04-04
Oracle中rank,over partition函數(shù)的使用方法
本文主要介紹Oracle中rank,over partition函數(shù)的用法,希望對大家有所幫助。2016-05-05

