JSON提取子键+值数组
Posted
技术标签:
【中文标题】JSON提取子键+值数组【英文标题】:JSON extract sub key+value array 【发布时间】:2021-02-03 21:05:37 【问题描述】:在 Oracle Pl/sql 中,type="complaint" 的以下 json 格式如何获取“partialSuccessWarning”元素全文数据值以进行进一步处理?
我是 json pl/sql 的新手,感谢任何帮助
JSON 数据:
[
"type": "customer",
"existingCount": 2,
"createdCount": 0,
"partialSuccessCount": 0,
"erroredCount": 0,
"totalCount": 8,
"createdRecords": [
],
"existingRecords": [
"791304",
"2154046"
],
"error":
,
"partialSuccessWarning":
,
"type": "complaint",
"existingCount": 3,
"createdCount": 2,
"partialSuccessCount": 3,
"erroredCount": 0,
"totalCount": 8,
"createdRecords": [
"VS-548982"
],
"existingRecords": [
"VS-548988",
"VS-548986",
"VS-548984"
],
"error":
,
"partialSuccessWarning":
"VS-548986": [
"[TLM-TEST-SERIAL] does not exist or could not be loaded."
],
"VS-548984": [
"[TLM-TEST-SERIAL] does not exist or could not be loaded."
],
"VS-548982": [
"[TLM-TEST-SERIAL] does not exist or could not be loaded."
]
]
【问题讨论】:
【参考方案1】:您可以直接使用带有JSON_TABLE()
函数的SQL,该函数从Oracle DB 12.1.0.2
版本开始可用,但是您需要获取值并进一步使用,然后通过创建存储函数将返回值分配给一些变量返回类型为SYS_REFCURSOR
如
CREATE OR REPLACE FUNCTION Get_Warnings RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
JsonArray VARCHAR2(32767);
arrWarnings VARCHAR2(1000);
v_sql VARCHAR2(32767);
BEGIN
JsonArray :='[
"type": "customer",
"existingCount": 2,
...
]';
arrWarnings := JSON_QUERY(JsonArray, '$');
DBMS_OUTPUT.PUT_LINE(arrWarnings);
v_sql :=
'SELECT "VS-548986","VS-548984","VS-548982"
FROM dual
CROSS JOIN JSON_TABLE(:Warnings,
''$'' COLUMNS(NESTED PATH ''$[*]."partialSuccessWarning"''
COLUMNS(
"VS-548986" VARCHAR2(1000) PATH ''$."VS-548986"[*]'',
"VS-548984" VARCHAR2(1000) PATH ''$."VS-548982"[*]'',
"VS-548982" VARCHAR2(1000) PATH ''$."VS-548982"[*]''
)
)
)';
OPEN v_recordset FOR v_sql USING arrWarnings;
RETURN v_recordset;
END;
/
然后从 SQL Developer 的控制台调用
SQL> DECLARE
result SYS_REFCURSOR;
BEGIN
:result := Get_Warnings;
END;
/
SQL> PRINT result ;
Demo
编辑:Oracle12c
内的JSON
有JSON_TABLE
、JSON_VALUE
和JSON_QUERY
的函数数量有限,而我们需要确定JSON
表达式的键。然后我们可以选择使用正则表达式函数来提取键值,以便动态构造 SQL 语句(v_sql
)和JSON_TABLE()
,以创建以下函数的方式,考虑到原始JSON
的简化形式格式如下
CREATE OR REPLACE FUNCTION Get_Warnings RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
JsonArray VARCHAR2(32767);
arrWarnings VARCHAR2(1000);
v_sql VARCHAR2(32767);
v_keys VARCHAR2(32767);
v_cols VARCHAR2(32767);
BEGIN
JsonArray :='[
"partialSuccessWarning":
"VS-548986": [
"aaa"
],
"VS-548984": [
"bbb"
],
"VS-548982": [
"ccc"
]
]';
arrWarnings := JSON_QUERY(JsonArray, '$');
WITH t(JA) AS
(
SELECT JSON_QUERY(JsonArray, '$[*]."partialSuccessWarning"')
FROM dual
), t2 AS
(
SELECT REGEXP_REPLACE( REGEXP_SUBSTR( JA , '[^[]+',1,level ), '(.*")(\S+)(":.*)', '\2') AS keys, level AS lvl
FROM t
CONNECT BY level <= REGEXP_COUNT( JA, '\["' )
)
SELECT LISTAGG( '"'||keys||'"',',') WITHIN GROUP (ORDER BY lvl),
LISTAGG( '"'||keys||'" VARCHAR2(1000) PATH ''$."'||keys||'"[*]''',',') WITHIN GROUP (ORDER BY lvl)
INTO v_keys, v_cols
FROM t2;
v_sql :=
'SELECT '||v_keys||
' FROM dual
CROSS JOIN JSON_TABLE(:Warnings,
''$'' COLUMNS(NESTED PATH ''$[*]."partialSuccessWarning"''
COLUMNS('||v_cols||')
)
)';
OPEN v_recordset FOR v_sql USING arrWarnings;
RETURN v_recordset;
END;
/
这会产生结果
VS-548986 | VS-548984 | VS-548982 |
---|---|---|
aaa | bbb | ccc |
【讨论】:
感谢您的回复..让我用简单的例子说清楚。下面是 myJSON 的示例 1)在我的情况下,列名“open”、“close”是动态的,但总会有两个……所以不确定如何通过不知道列的位置表示法读取 2)作为一种解决方法,我想我会循环遍历“数据”键、值……但是如何获取“数据”全文? VS-548986,VS-548984 在我的情况下是动态的。实际上,目标是在“partialSuccessWarning”下打印那些任何帮助表示赞赏 好吧,我已经添加了动态案例@RaviKiran以上是关于JSON提取子键+值数组的主要内容,如果未能解决你的问题,请参考以下文章