Как пройти через строку json с PL / SQL? - PullRequest
0 голосов
/ 28 мая 2019

Мой пример возвращает только 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;

Ответы [ 2 ]

2 голосов
/ 28 мая 2019

TL; DR - вы не можете, поскольку у вас есть дубликаты ключей в объекте.


Из стандарта JSON - RFC 7159

  1. Предметы

    Структура объекта представлена ​​в виде пары фигурных скобок окружающий ноль или более пар имя / значение (или членов). Имя это строка. После каждого имени стоит двоеточие, отделяя имя от стоимости. Одна запятая отделяет значение от следующего название. Имена внутри объекта ДОЛЖНЫ быть уникальными.

(добавлен акцент)

{"NAME":"AUDI","YEAR":"2000","NAME":"BMW","YEAR":"2010"}

Хотя технически это синтаксически правильный JSON, это не имеет смысла, так как вы дублируете ключи, так что большинство (каждый) парсеров JSON, следующих RFC 7159, перезапишут первый экземпляр ключа с более поздними вхождениями, чтобы ваш JSON был эффективен:

{"NAME":"BMW","YEAR":"2010"}

И вы не можете получить AUDI / 2000 из вывода (если вы не проанализируете JSON вручную).

Если вы хотите отправить несколько значений, вам следует использовать массив:

[{"NAME":"AUDI","YEAR":"2000"},{"NAME":"BMW","YEAR":"2010"}]

Обновление

Вы можете попробовать:

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;

или (если 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;
1 голос
/ 28 мая 2019

Поскольку вы используете 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.
...