如何使用 PL/SQL 循环遍历 json 响应?
Posted
技术标签:
【中文标题】如何使用 PL/SQL 循环遍历 json 响应?【英文标题】:How to loop through a json response with PL/SQL? 【发布时间】:2020-05-29 08:27:07 【问题描述】:当我的 json 响应如下时,我遇到了一个问题:
declare
sample_json varchar2 (32767)
:= '"items": ["NAME":"AUDI","YEAR":"2000","NAME":"BMW","YEAR":"2010"]';
BEGIN
for rec IN (
select j.name,j.year
from json_table(sample_json,'$[*]' COLUMNS
name varchar2(20) PATH '$.items[0].NAME',
year NUMBER PATH '$.items[0].YEAR'
) j )
LOOP
dbms_output.put_line (rec.name||','||rec.year);
END LOOP;
END;
/
我必须使用 $.items[0].NAME 来获取一个值,但我想让它动态化,以便它可以循环给我两个值。
【问题讨论】:
【参考方案1】:也可以在纯 PL/SQL 中进行解析。考虑以下可重现的示例:
declare
jdoc varchar2 (32767) :=
'"items": ["NAME":"AUDI","YEAR":"2000","NAME":"BMW","YEAR":"2010"]';
jobj json_object_t;
keys json_key_list;
jarr json_array_t;
begin
jobj := json_object_t (jdoc);
keys := jobj.get_keys;
jarr := jobj.get_array (keys(1));
for ai in 0..jarr.get_size ()-1 loop
jobj := treat (jarr.get(ai) as json_object_t);
keys := jobj.get_keys;
for ki in 1..keys.count loop
dbms_output.put_line (keys(ki)||'='||jobj.get_string (keys(ki)));
end loop;
end loop;
end;
/
PL/SQL procedure successfully completed.
NAME=AUDI
YEAR=2000
NAME=BMW
YEAR=2010
【讨论】:
【参考方案2】:我无法完全理解您对使查询动态化的需求,但也许下面的脚本可以让您对使用 JSON_VALUE 和编写动态 plsql 语句有所了解。
DECLARE
SAMPLE_JSON VARCHAR2 (32767)
:= '"items": ["NAME":"AUDI","YEAR":"2000","NAME":"BMW","YEAR":"2010"]';
V_RESULT_NAME VARCHAR2 (500);
V_RESULT_YEAR VARCHAR2 (500);
V_KEY VARCHAR (200) := 'items[0].NAME';
V_KEY2 VARCHAR (200) := 'items[0].YEAR';
BEGIN
EXECUTE IMMEDIATE 'SELECT JSON_VALUE(:1,''$.' || V_KEY || ''') FROM DUAL'
INTO V_RESULT_NAME
USING SAMPLE_JSON;
DBMS_OUTPUT.PUT_LINE (V_RESULT_NAME );
END;
/
您可以在此处将 json 数据中的值动态插入到您的表中。
DECLARE
SAMPLE_JSON VARCHAR2 (32767)
:= '"items": ["NAME":"AUDI","YEAR":"2000","NAME":"BMW","YEAR":"2010"]';
BEGIN
FOR REC IN (
SELECT J.NAME,J.YEAR
FROM JSON_TABLE(SAMPLE_JSON,'$[*]' COLUMNS
NAME VARCHAR2(20) PATH '$.items[0].NAME',
YEAR NUMBER PATH '$.items[0].YEAR'
) J )
LOOP
EXECUTE IMMEDIATE 'INSERT INTO YOUR_TABLE(NAME,YEAR) VALUES('||REC.NAME||','||REC.YEAR||'); COMMIT;'
-- DBMS_OUTPUT.PUT_LINE (REC.NAME||','||REC.YEAR);
END LOOP;
END;
/
不使用索引。
DECLARE
SAMPLE_JSON VARCHAR2 (32767)
:= '"items": ["NAME":"AUDI","YEAR":"2000","NAME":"BMW","YEAR":"2010","NAME":"TOFAS","YEAR":"1995"]';
BEGIN
FOR REC IN (
SELECT J.NAME,J.YEAR
FROM JSON_TABLE(SAMPLE_JSON,'$.items[*]' COLUMNS
NAME VARCHAR2(20) PATH '$.NAME',
YEAR NUMBER PATH '$.YEAR'
) J )
LOOP
--EXECUTE IMMEDIATE 'INSERT INTO YOUR_TABLE(NAMEE,YEARR) VALUES('||REC.NAME||','||REC.YEAR||'); COMMIT;';
DBMS_OUTPUT.PUT_LINE (REC.NAME||','||REC.YEAR);
END LOOP;
END;
/
注意:如果您想动态描述 json 数据中的列,我知道 oracle 无法做到这一点。使用前必须将 json 标签一一描述为 JSON_TABLE 列。
【讨论】:
要求基本上是遍历json响应,以便我们可以插入到数据库表中。上面只是示例示例,我们可以有 10-20 个 json 对象作为响应,我们需要循环以便获取数据库表中的所有 NAME、YEAR 列。 但是你的问题已经有了一个很好的循环 json 数据的方法。为什么你不能使用你已经拥有的?看看我编辑了我的答案。 @Vikash 是的,但这只会给我作为 AUDI,2000 的输出。由于路径具有硬编码索引 $.items[0].NAME。那么想象一下 10 条这样的记录?我想要一种可以获得所有值的方法。 那你为什么还要坚持使用[0]。您可以通过我的第三次编辑来实现您的目标。检查出。 @Vikash以上是关于如何使用 PL/SQL 循环遍历 json 响应?的主要内容,如果未能解决你的问题,请参考以下文章