如何使用 PL/SQL 循环 json 字符串?

Poi*_*ter 0 oracle plsql oracle12c

我的示例仅返回BMW 2010. 我怎样才能让它AUDI 2000返回BMW 2010

declare
    sample_json   varchar2 (32767)
        := '

            [{"NAME":"AUDI","YEAR":"2000"},{"NAME":"BMW","YEAR":"2010"}]
';
begin
    apex_json.parse (sample_json);
    dbms_output.put_line (apex_json.get_varchar2 ('NAME'));
    dbms_output.put_line (apex_json.get_varchar2 ('YEAR'));
end;
Run Code Online (Sandbox Code Playgroud)

MT0*_*MT0 5

TL;DR - 你不能,因为对象中有重复的键。


来自 JSON 标准 - RFC 7159

  1. 对象

对象结构表示为一对围绕零个或多个名称/值对(或成员)的大括号。名称是一个字符串。每个名称后面都有一个冒号,将名称与值分开。单个逗号将值与后面的名称分隔开。 对象内的名称应该是唯一的。

(增加强调)

{"NAME":"AUDI","YEAR":"2000","NAME":"BMW","YEAR":"2010"}
Run Code Online (Sandbox Code Playgroud)

虽然从技术上讲,它是语法正确的 JSON,但它没有意义,因为您正在复制键,因此遵循 RFC 7159 的大多数(每个)JSON 解析器都会用后来出现的键覆盖第一个实例,以便您的 JSON 有效:

{"NAME":"BMW","YEAR":"2010"}
Run Code Online (Sandbox Code Playgroud)

并且您无法从输出中获取AUDI/ 2000(除非您手动解析 JSON)。

如果您想发送多个值,那么您应该使用数组:

[{"NAME":"AUDI","YEAR":"2000"},{"NAME":"BMW","YEAR":"2010"}]
Run Code Online (Sandbox Code Playgroud)

更新

你可以试试:

declare
  sample_json varchar2(32767) := '{"data":[{"NAME":"AUDI","YEAR":"2000"},{"NAME":"BMW","YEAR":"2010"}]}';
begin
  apex_json.parse (sample_json);
  dbms_output.put_line (apex_json.get_varchar2 ('data[1].NAME'));
  dbms_output.put_line (apex_json.get_varchar2 ('data[1].YEAR'));
  dbms_output.put_line (apex_json.get_varchar2 ('data[2].NAME'));
  dbms_output.put_line (apex_json.get_varchar2 ('data[2].YEAR'));
end;
Run Code Online (Sandbox Code Playgroud)

或者(如果 apex 接受数组作为其外部对象):

declare
    sample_json varchar2(32767) := '[{"NAME":"AUDI","YEAR":"2000"},{"NAME":"BMW","YEAR":"2010"}]';
begin
  apex_json.parse (sample_json);
  FOR i IN 1 .. 2 LOOP
    dbms_output.put_line (apex_json.get_varchar2(p_path=>'[%d].NAME',p0=>i));
    dbms_output.put_line (apex_json.get_varchar2(p_path=>'[%d].YEAR',p0=>i));
  END LOOP;
end;
Run Code Online (Sandbox Code Playgroud)


Kau*_*yak 5

由于您运行的是 Oracle 12c,因此不需要 Apex_json。您可以使用标准 Oracle 的 JSON 函数。

set serveroutput on
declare
sample_json   varchar2 (32767)
        := '[{"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 '$.NAME',
        year NUMBER       PATH '$.YEAR'
       ) j  ) 
     LOOP
       dbms_output.put_line (rec.name||','||rec.year);
     END LOOP;
END;
/



AUDI,2000
BMW,2010


PL/SQL procedure successfully completed.
Run Code Online (Sandbox Code Playgroud)