oracle12C資料庫JSON的應用 --PL/SQL儲存過程中JSON解析應用篇
阿新 • • 發佈:2018-11-20
最近有些專案在資料庫oracle中使用到json格式的資料互動,對於oracle12以上的版本都支援JSON格式資料的使用,剛剛接觸的猿們可以到上一篇oracle資料庫使用json的簡單入門,最好參考官方的API文件關於oracle官方API文件對JSON的支援;
下面就比較詳細的說一下,關於oracle資料庫在儲存過程中的JSON解析應用:
一:先上一段儲存過程解析JSON的儲存過程,看你們能不能看的懂。
看不懂沒關係,後面我會慢慢的分析怎麼解析json。
/* JSON_IN 的json格式(僅供參考): { "procedureNameFlag": "xxx", "param_in": [{ "PROD_PLANT": "xxx", "MODEL_NAME": "xxx" }], "doAfter": "xxx", "tableName": "xxx", "tableIndex": "xxx", "curSchema": "xxx", "funCode": "xxx", "ObjI_Button": "xxx", "empNo": "xxx" }*/ CREATE OR REPLACE PROCEDURE PRC_JSON_TEST(JSON_IN IN VARCHAR2, RES_OUT OUT VARCHAR2) IS JSON_OBJ JSN; PARAM_IN_LIST JSN_LIST; PARAM_OBJ JSN; PROD_PLANT_P C_EMP_T.PLANT%TYPE; MODEL_NAME_P C_NAME_T.NAME%TYPE; cnt_p NUMBER(10); LOCATION_P VARCHAR2(10); OPERATE_P VARCHAR2(10); PROD_CATEGORY_NAME_p VARCHAR2(40); O_PROD_CATEGORY_NAME_p VARCHAR2(40); I NUMBER(5); begin RES_OUT := '{"RES":"OK","MSG":""}'; --解析JSON引數 BEGIN JSON_OBJ := JSN(JSON_IN); IF NOT ((REPLACE(JSON_OBJ.get('procedureNameFlag').TO_CHAR, '"', '') = 'doAfter') AND ((REPLACE(JSON_OBJ.get('ObjI_Button').TO_CHAR, '"', '') = 'ADD') OR (REPLACE(JSON_OBJ.get('ObjI_Button').TO_CHAR, '"', '') = 'UPDATE'))) THEN IF NOT ((REPLACE(JSON_OBJ.get('procedureNameFlag').TO_CHAR, '"', '') = 'doBefore') AND (REPLACE(JSON_OBJ.get('ObjI_Button').TO_CHAR, '"', '') = 'ADD' )) THEN RETURN; END IF; END IF; LOCATION_P := REPLACE(JSON_OBJ.get('procedureNameFlag').TO_CHAR, '"', ''); OPERATE_P := REPLACE(JSON_OBJ.get('ObjI_Button').TO_CHAR, '"', ''); PARAM_IN_LIST := JSN_LIST(JSON_OBJ.get('param_in').TO_CHAR); I := 1; WHILE I <= PARAM_IN_LIST.COUNT LOOP --PARAM_OBJ := JSN(JSON_OBJ.get('param_in').TO_CHAR); PARAM_OBJ := JSN(PARAM_IN_LIST.GET(I).TO_CHAR); MODEL_NAME_P := PARAM_OBJ.get('MODEL_NAME').TO_CHAR; MODEL_NAME_P := REPLACE(MODEL_NAME_P, '"', ''); PROD_PLANT_P := PARAM_OBJ.get('PROD_PLANT').TO_CHAR; PROD_PLANT_P := REPLACE(PROD_PLANT_P, '"', ''); PROD_CATEGORY_NAME_P := PARAM_OBJ.get('PROD_CATEGORY_NAME').TO_CHAR; PROD_CATEGORY_NAME_P := REPLACE(PROD_CATEGORY_NAME_P, '"', ''); IF ((LOCATION_P='doAfter') AND (OPERATE_P='ADD')) THEN BEGIN SELECT count(model_name) INTO cnt_p FROM C_MODEL_DESC_T A WHERE A.MODEL_NAME = MODEL_NAME_P AND ROWNUM=1; IF cnt_p=0 THEN INSERT INTO C_MODEL_DESC_T (MODEL_NAME, CREATE_EMP) SELECT A.MODEL_NAME, A.CREATE_EMP FROM C_PROD_PLANT_MODEL_T A WHERE PROD_PLANT = PROD_PLANT_P AND MODEL_NAME = MODEL_NAME_P; END IF; EXCEPTION WHEN OTHERS THEN DELETE FROM C_PROD_PLANT_MODEL_T A WHERE PROD_PLANT = PROD_PLANT_P AND MODEL_NAME = MODEL_NAME_P; END; UPDATE C_PROD_PLANT_MODEL_T SET PROD_CATEGORY_NAME = PROD_CATEGORY_NAME_P WHERE MODEL_NAME = MODEL_NAME_P AND PROD_CATEGORY_NAME IS NULL; COMMIT; ELSIF ((LOCATION_P='doAfter') AND (OPERATE_P='UPDATE')) THEN BEGIN SELECT PROD_CATEGORY_NAME INTO O_PROD_CATEGORY_NAME_p FROM C_PROD_PLANT_MODEL_T WHERE MODEL_NAME = MODEL_NAME_P AND PROD_CATEGORY_NAME IS NOT NULL AND ROWNUM = 1; IF O_PROD_CATEGORY_NAME_P <> PROD_CATEGORY_NAME_P THEN UPDATE C_PROD_PLANT_MODEL_T SET PROD_CATEGORY_NAME = PROD_CATEGORY_NAME_P WHERE MODEL_NAME = MODEL_NAME_P; ELSE UPDATE C_PROD_PLANT_MODEL_T SET PROD_CATEGORY_NAME = PROD_CATEGORY_NAME_P WHERE MODEL_NAME = MODEL_NAME_P AND PROD_CATEGORY_NAME IS NULL; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN UPDATE C_PROD_PLANT_MODEL_T SET PROD_CATEGORY_NAME = PROD_CATEGORY_NAME_P WHERE MODEL_NAME = MODEL_NAME_P AND PROD_CATEGORY_NAME IS NULL; END; COMMIT; ELSIF ((LOCATION_P='doBefore') AND (OPERATE_P='ADD')) THEN BEGIN SELECT PROD_CATEGORY_NAME INTO O_PROD_CATEGORY_NAME_p FROM C_PROD_PLANT_MODEL_T WHERE MODEL_NAME = MODEL_NAME_P AND PROD_CATEGORY_NAME IS NOT NULL AND ROWNUM = 1; IF O_PROD_CATEGORY_NAME_P <> PROD_CATEGORY_NAME_P THEN RES_O := '{"RES":"NG","MSG":"Prod Category must be '||O_PROD_CATEGORY_NAME_P||'"}'; RETURN; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN; END; END IF; I := I+1; END LOOP; EXCEPTION WHEN OTHERS THEN --RES_O := '{"RES":"NG","MSG":"Input Parameters Error!"}'; RES_O := '{"RES":"NG","MSG":"ORACLE ERROR:' || REPLACE(dbms_utility.format_error_backtrace(), '"', '') || '"}'; ROLLBACK; RETURN; END; end;
二.詳細解析在oracle中使用json
從簡單的說起。。。
1.先建立一個儲存過程:
CREATE OR REPLACE PROCEDURE PRC_JSON_TEST(param_in IN VARCHAR2, result_out OUT VARCHAR2)
包含兩個引數,一個IN引數:用來接受傳入json格式字串資料的引數;一個OUT引數:用來返回輸出執行儲存過程之後的結果資訊。
2.宣告變數,用於接受解析json變數(需要根據自己實際需要去宣告變數)
count BINARY_INTEGER; --宣告一個有符號整型變數count json_obj JSN; --宣告一個JSON物件變數json_obj param_obj JSN; --宣告一個JSON物件變數param_obj KIND_NAME_V C_DUTY_T.KIND_NAME%TYPE; --宣告一個型別是某張表某個欄位型別屬性的變數 PARAM_IN_LIST JSN_LIST; --宣告一個JSON陣列變數 i NUMBER(5);
說明一下:param_in傳入的JSON字元資料的引數,其格式可以包含多種(基本的格式只有兩種,一種是json陣列,另一種是json物件;兩者可以相互巢狀),有JSONArray巢狀JSONObject或相互巢狀、或JSONObject中的value值又巢狀JSONObject或JSONArray等等。本次我使用的json格式是JSONObject中的value巢狀JSONArray和JSONObject:
/* param_in 傳入的json引數*/ { "param_in": [{ "PROD": "CA00", "NAME": "123123" }], "name": "tiger", "age": "one", "sex": "1", "address": "232", }
3.解析json過程,實現自己的功能邏輯
--解析傳入json格式字串並賦值給json物件變數,使用JSN()解析
json_obj :=JSN(param_in);
--使用get()方法獲取json_obj中key對應的value值,其value值是個json陣列列表,使用JSN_LIST()解析
PARAM_IN_LIST :=JSN_LIST(json_obj.get('param_in').TO_CHAR);
--獲取json陣列下標為1的值,其值是json物件,使用JSN()解析;
param_obj :=JSN(PARAM_IN_LIST.GET(1).TO_CHAR);
--當然如果是json陣列多個值的話,可以使用迴圈遍歷,下面使用 WHILE ..LOOP..方法,你也可以使用FOR..IN(..)...LOOP方法遍歷
--PARAM_IN_LIST.COUNT獲取json陣列的長度
WHILE i<=PARAM_IN_LIST.COUNT LOOP
--自己的邏輯功能
END LOOP
後面就可以參考上面的基本方法,回頭自己研究上上面的儲存過程了