Преобразование строки в объект JSON с использованием Oracle PL / SQL - PullRequest
0 голосов
/ 05 июля 2019

У меня есть файл "input.json" в каталоге данных Oracle.Я могу прочитать файл в своем коде PL / SQL с помощью команды UTL_FILE.Теперь они представлены в строковом формате, и я хотел бы преобразовать их в строку JSON и проанализировать их все с использованием блока PL / SQL.Я использую oracle 12.2.

Это содержимое моего входного файла JSON:

{
    "CAR":["%HON%","%UZU%"],
    "NAME":["%RAY%","%OE%"];
}
Create or Replace procedure TEST1 as
    fHandle   UTL_FILE.FILE_TYPE;
    s varchar(200);
    -- begin Reading of code
BEGIN
     fHandle := UTL_FILE.FOPEN('DISCOVERY', 'input.json', 'r');
     Loop
         UTL_FILE.get_line(fHandle,s);
         dbms_output.put_line(s);
     end loop; 
     UTL_FILE.fclose(fHandle);
END;

ожидаемый вывод - допустимая строка JSON

CAR:"%HON%"
CAR:"%UZU%"
NAME:"%RAY%"
NAME:"%OE%"

Ответы [ 3 ]

2 голосов
/ 08 июля 2019

Вы можете:

  • Создать внешнюю таблицу для чтения файла
  • Использовать JSON_table для преобразования документа в реляционные строки-столбцы

Это выглядит примерно так:

/* Create the file */
create or replace directory tmp as '/tmp';
declare
  f utl_file.file_type;
begin
  f := utl_file.fopen ('TMP', 'input.json', 'w');
  utl_file.put_line ( f, '{ "CAR":["%HON%","%UZU%"], "NAME":["%RAY%","%OE%"] }');
  utl_file.fclose(f);
end;
/

create table json_ext (
  json_doc varchar2(100)
) organization external (
  default directory tmp
  access parameters (
    records delimited by newline
    fields (
      json_doc char(1000)
    )
  )
  location ( 'input.json' )
);

select * from json_ext;

JSON_DOC                                               
{ "CAR":["%HON%","%UZU%"], "NAME":["%RAY%","%OE%"] } 

select * 
from   json_ext, 
       json_table (
         json_doc, '$'
         columns (
           nested path '$.CAR[*]' columns (
             CAR path '$'
           ),
           nested path '$.NAME[*]' columns (
             NAME path '$'
           )
         )
       );

JSON_DOC                                                CAR       NAME     
{ "CAR":["%HON%","%UZU%"], "NAME":["%RAY%","%OE%"] }    %HON%     <null>    
{ "CAR":["%HON%","%UZU%"], "NAME":["%RAY%","%OE%"] }    %UZU%     <null>    
{ "CAR":["%HON%","%UZU%"], "NAME":["%RAY%","%OE%"] }    <null>    %RAY%     
{ "CAR":["%HON%","%UZU%"], "NAME":["%RAY%","%OE%"] }    <null>    %OE%   

Это разбивает каждый массив на собственный набор строк и столбцов.Чтобы получить это как единый список имен атрибутов и значений массива, вы можете unpivot результаты:

with rws as (
  select j.* 
  from   json_ext, 
         json_table (
           json_doc, '$'
           columns (
             nested path '$.CAR[*]' columns (
               CAR path '$'
             ),
             nested path '$.NAME[*]' columns (
               NAME path '$'
             )
           )
         ) j
) 
  select * from rws 
  unpivot ( 
    val for attr in ( CAR, NAME )
  );

ATTR    VAL     
CAR     %HON%    
CAR     %UZU%    
NAME    %RAY%    
NAME    %OE%  
0 голосов
/ 05 июля 2019

Вы можете сделать это используя регулярные выражения:

Create or Replace procedure TEST1 as
  fHandle   UTL_FILE.FILE_TYPE;
  s varchar(200);
BEGIN
  fHandle := UTL_FILE.FOPEN('DISCOVERY', 'input.json', 'r');

  WHILE TRUE LOOP
    BEGIN
      UTL_FILE.get_line(fHandle, s);

      IF s <> '{' AND s <> '}' THEN
        FOR aRow IN (SELECT REGEXP_SUBSTR(s, '[^:]*', 1, 1) AS COL1,
                            REGEXP_SUBSTR(s, '"%[^,]*%"', 1, 1) AS COL2,
                            REGEXP_SUBSTR(s, '"%[^,]*%"', 1, 2) AS COL3
                       FROM DUAL)
        LOOP
          DBMS_OUTPUT.PUT_LINE(COL1 || ':' || COL2);
          DBMS_OUTPUT.PUT_LINE(COL1 || ':' || COL3);
        END LOOP;
      END IF;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        EXIT;
    END;
  end loop; 

  UTL_FILE.fclose(fHandle);
END TEST1;
0 голосов
/ 05 июля 2019

Это требует циклической обработки элементов JSON, а затем элементов массива. Идеи заимствованы из этого поста

SET SERVEROUTPUT ON
DECLARE
     l_json CLOB := '{
    "CAR" :["%HON%","%UZU%"],
    "NAME":["%RAY%","%OE%" ]
}';
     l_json_obj json_object_t;
     l_keys json_key_list;
     l_arr json_array_t;
     elem json_element_t;
BEGIN
     l_json_obj := json_object_t(l_json);
     l_keys := l_json_obj.get_keys;
     FOR i IN 1..l_keys.count LOOP
          l_arr :=  l_json_obj.get_array(l_keys(i));
          FOR j IN 0..l_arr.get_size - 1 LOOP
               elem := l_arr.get(j);
               dbms_output.put(l_keys(i)
                               || ':');
               dbms_output.put_line(elem.stringify);
          END LOOP;

     END LOOP;

END;
/

Результат

CAR:"%HON%"
CAR:"%UZU%"
NAME:"%RAY%"
NAME:"%OE%"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...