Как перенести одну строку в столбец для преобразования в JSON в Oracle Database 12.1? - PullRequest
0 голосов
/ 23 января 2019

Ситуация следующая:

У меня есть одна строка (из запроса).Данные из этой строки должны быть отправлены на сервер в формате JSON, где каждая запись данных в файле JSON представляет собой комбинацию

"{column_name}": "{column_value}".

Для этого конкретного случаявходные данные

nr | a  | b    |
---|----|------|
1  | 10 | text |

и выходные данные должны быть

{
  "a": 10,
  "b": "text"
}

Как динамически генерировать объект JSON в PL / SQL на основе неизвестного набора столбцов?Требуется ли перенос строки?Если да, то как?

1 Ответ

0 голосов
/ 23 января 2019

Поскольку вы используете 12cR1, вы не можете использовать JSON-генерирующую функциональность, добавленную в 12cR2. Существуют доступные пакеты ( PL / JSON ), но если у вас есть только одна эта задача, вы потенциально можете выполнить свою собственную, используя пакет dbms_sql.

В качестве довольно простого (!) Примера, если взять одну строку, как указано в вопросе, вы можете сделать что-то вроде:

declare
  -- for query text
  l_query varchar2(4000);
  -- for fetching query results
  l_varchar2 varchar2(4000);
  l_number number;
  l_date date;
  l_timestamp timestamp;
  -- for generated JSON string
  l_json varchar2(4000);
  -- for dbms_sql calls
  l_c pls_integer;
  l_col_cnt pls_integer;
  l_desc_t dbms_sql.desc_tab3;
  l_rc pls_integer;
begin
  -- arbitrary query
  l_query := 'select a, b, c from your_table where nr = 1';

  l_c := dbms_sql.open_cursor;
  dbms_sql.parse(l_c, l_query, dbms_sql.native);
  dbms_sql.describe_columns3(c => l_c, col_cnt => l_col_cnt, desc_t => l_desc_t);

  for i in 1..l_col_cnt loop
    case l_desc_t(i).col_type
      when 1 then
        dbms_sql.define_column(l_c, i, l_varchar2, 4000);
      when 2 then
        dbms_sql.define_column(l_c, i, l_number);
      when 12 then
        dbms_sql.define_column(l_c, i, l_date);
      when 180 then
        dbms_sql.define_column(l_c, i, l_timestamp);
      -- more types as needed
      else raise_application_error(-20001, 'Unknown data type ' || l_desc_t(i).col_type);
    end case;
  end loop;

  l_rc := dbms_sql.execute(l_c);
  l_rc := dbms_sql.fetch_rows(l_c);

  l_json := '{' || chr(10);

  for i in 1..l_col_cnt loop
    -- name
    l_json := l_json || ' "' || l_desc_t(i).col_name || '": ';
    -- value
    case l_desc_t(i).col_type
      when 1 then
        dbms_sql.column_value(l_c, i, l_varchar2);
        l_json := l_json || '"' || l_varchar2 || '"';
      when 2 then
        dbms_sql.column_value(l_c, i, l_number);
        l_json := l_json || l_number;
      when 12 then
        dbms_sql.column_value(l_c, i, l_date);
        l_json := l_json || '"' || to_char(l_date, 'YYYY-MM-DD"T"HH24:MI:SS') || '"';
      when 180 then
        dbms_sql.column_value(l_c, i, l_timestamp);
        l_json := l_json || '"' || to_char(l_timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.FF3') || '"';
      -- more types as needed
      else raise_application_error(-20001, 'Unknown data type ' || l_desc_t(i).col_type);
    end case;
    if i < l_col_cnt then
      l_json := l_json || ',';
    end if;
    l_json := l_json || chr(10);
  end loop;

  l_json := l_json || '}';

  dbms_sql.close_cursor(l_c);

  -- for debugging, to see generated value
  dbms_output.put_line(l_json);
end;
/

Вы, вероятно, передадите запрос и получите JSON из функции или процедуры, используя аналогичный механизм. И вам может понадобиться CLOB для хранения сгенерированного JSON; и проверки ошибок и т.д ...

С образцом таблицы с добавленным столбцом даты для развлечения:

create table your_table (nr, a, b, c) as
select 1, 10, cast('text' as varchar2(30)), sysdate from dual;

, который получает:

{
 "A": 10,
 "B": "text",
 "C": "2019-01-23T07:14:43"
}


PL/SQL procedure successfully completed.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...