Oracle解析JSON字符串
假设某个字段存储的JSON字符串,我们不想查出来后通过一些常见的编程语言处理(
JSON.parse()
或者是JSONObject.parseObject()
等),想直接在数据库上处理,又该如何书写呢?
其实在ORACLE
中也支持多种机制去处理JSON数据,例如有操作函数JSON_ARRAY、JSON_EXISTS、JSON_VALUES、JSON_TABLE、JSON_QUERY等可以像MongoDB
一样操作JSON数据。
但是一般开发中很少使用JSON操作函数,都是像其他语言一样直接解析成JSON对象或数组灵活操作数据,例如:
DECLARE
-- 申明一个json字符串
V_STR NVARCHAR2(1000) := '[
{ "name": "alex", "age": 15, "high": 10, "phone": 1358226000000 },
{ "name": "jan", "age": 16, "high": 92, "phone": 1358226000000 },
{ "name": "jan", "age": 17, "high": 45, "phone": 1358226000000 },
{ "name": "alex", "age": 18, "high": 87, "phone": 1358226000000 },
{ "name": "jan", "age": 15, "high": 10, "phone": 1358226060000 },
{ "name": "alex", "age": 16, "high": 87, "phone": 1358226060000 },
{ "name": "alex", "age": 17, "high": 45, "phone": 1358226060000 },
{ "name": "jan", "age": 18, "high": 92, "phone": 1358226060000 }]';
-- 申明一个json数组变量(相当于const v_array = [])
V_ARRAY JSON_ARRAY_T;
-- 申明一个json对象变量(相当于const v_object = {})
V_OBJECT JSON_OBJECT_T;
-- 用于接收json key集合
V_KEY_LIST JSON_KEY_LIST;
-- 记住这几个关键字就行了,实际开发中已经够用了
BEGIN
-- V_ARRAY := JSON_ARRAY_T(V_STR); -- 解析成json数组(这样书写也可以)
-- 解析成json数组
V_ARRAY := JSON_ARRAY_T.PARSE(V_STR);
-- 遍历json数组
FOR I IN 0 .. V_ARRAY.GET_SIZE - 1 LOOP
-- 解析成json对象
-- V_OBJECT := JSON_OBJECT_T.PARSE('{"A":1}'); 如果是字符串可以直接使用parse()
V_OBJECT := JSON_OBJECT_T(V_ARRAY.GET(I));
-- 获取 phone 属性值
DBMS_OUTPUT.PUT_LINE('phone' || ' = ' || V_OBJECT.GET_STRING('phone'));
-- 新增 password 属性
V_OBJECT.PUT('password', '1');
DBMS_OUTPUT.PUT_LINE('password' || ' = ' || V_OBJECT.GET_STRING('password'));
-- 删除 high 属性
V_OBJECT.REMOVE('high');
DBMS_OUTPUT.PUT_LINE('high' || ' = ' || V_OBJECT.GET_STRING('high'));
-- 获取json对象的 key_list
V_KEY_LIST := V_OBJECT.GET_KEYS;
-- 变量 key_list
FOR KEY_INDEX IN 1 .. V_KEY_LIST.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(V_KEY_LIST(KEY_INDEX)); -- 输出 key
END LOOP;
END LOOP;
END;
JSON_OBJECT_T
GET开头的API
JSON_ARRAY_T
GET开头的API
当然两种类型的API远不止如此,用到的时候查阅一下即可。
在自定义函数上的使用示例
CREATE OR REPLACE FUNCTION YTGZHDB.FUN_GET_TDYT_NAME(TDYT IN NVARCHAR2) RETURN NVARCHAR2
AS
V_NAME NVARCHAR2(100);
V_KEY_LIST JSON_KEY_LIST;
V_JSON JSON_OBJECT_T;
V_TEMP NVARCHAR2(100);
V_DIC_ID VARCHAR2(50) := '402886cb84ae206e0184be15c1590753'; -- 土地用途(后续变更调整即可)
V_DIC_SQL VARCHAR2(255) := 'SELECT DI.F_NAME FROM YTGZHDB.DC_DIC_ITEM DI WHERE DI.F_VALUE = :1 AND DI.FK_DIC_ID = :2';
BEGIN
V_JSON := JSON_OBJECT_T.PARSE(TDYT);
V_KEY_LIST := V_JSON.GET_KEYS;
FOR I IN 1 .. V_KEY_LIST.COUNT
LOOP
EXECUTE IMMEDIATE V_DIC_SQL INTO V_TEMP USING V_KEY_LIST(I), V_DIC_ID;
V_NAME := CONCAT(V_NAME, CONCAT(V_TEMP, ','));
END LOOP;
RETURN SUBSTR(V_NAME, 1, (LENGTH(V_NAME) - 1));
END FUN_GET_TDYT_NAME;