Возвращает результаты sql-запроса как JSON в oracle 12c

фон

мне нужно получить несколько тысяч строк из Oracle и преобразовать их в JSON для использования в SlickGrid. В настоящее время я извлекаю строки в PHP, конвертируя их из ISO в UTF-8 с помощью iconv и экспортируя в json с помощью json_encode. Вся операция занимает около 1 секунды на стороне DB и 5 секунд для генерации JSON. Это долгий путь.

вопрос

Я прочитал, что Oracle 12c поддерживает JSON, но я не могу найти именно то, что мне нужно.

есть ли способ вернуть результат стандартного sql-запроса в формате json?

предположительно, я хотел бы выдать запрос, подобный этому:

SELECT * from table AS JSON

и получите действительный json, подобный этому:

[{"col1": "value1", "col2": 2}, {"col1": "valueOfRow2", "col2": 3}]

важно то, что мне нужно, чтобы последовательности unicode экранировались для меня, поскольку я использую кодировку ISO-8859-2 на стороне клиента, а JSON должен быть в UTF-8 или иметь экранированные последовательности.

6 ответов


Oracle 12c версии 12.1.0.2 (последняя версия по состоянию на 11.11.2014) добавляет поддержку JSON: https://docs.oracle.com/database/121/NEWFT/chapter12102.htm#BGBGADCC

он доступен с 17 октября. https://blogs.oracle.com/db/entry/oracle_database_12c_release_1

Если вы не можете исправить / работать с этой версией, есть отличный пакет, написанный Льюисом Каннингемом и Джонасом Крогсбоеллом: PL / JSON * http://pljson.sourceforge.net/

Это отличный пакет (я использовал его в многочисленных установках базы данных).

включенные примеры хороши и охватывают большинство сценариев.

declare 
  ret json;
begin
  ret := json_dyn.executeObject('select * from tab');
  ret.print;
end;
/

12cR2 (доступно в Oracle Cloud) поддерживает Это изначально.

SQL> select JSON_ARRAY(EMPLOYEE_ID, FIRST_NAME,LAST_NAME) from HR.EMPLOYEES;

JSON_ARRAY(EMPLOYEE_ID,FIRST_NAME,LAST_NAME)
--------------------------------------------------------------------------------
[100,"Steven","King"]
[101,"Neena","Kochhar"]

или

SQL> select JSON_OBJECT('ID' is EMPLOYEE_ID , 'FirstName' is FIRST_NAME,'LastName' is LAST_NAME) from HR.EMPLOYEES;

JSON_OBJECT('ID'ISEMPLOYEE_ID,'FIRSTNAME'ISFIRST_NAME,'LASTNAME'ISLAST_NAME)
----------------------------------------------------------------------------
{"ID":100,"FirstName":"Steven","LastName":"King"}
{"ID":101,"FirstName":"Neena","LastName":"Kochhar"}

вы можете использовать xmltype для преобразования результата SQL в XML и JSON. См. следующую статью для решения, которое будет работать для Oracle с версии 9. Вы также можете скачать пакет itstar_xml_util:

http://stefan-armbruster.com/index.php/12-it/pl-sql/12-oracle-xml-and-json-goodies

простой пример с таблицей emp:

declare
  l_sql_string varchar2(2000);
  l_xml        xmltype;
  l_json       xmltype;
begin
  l_sql_string := 'select a.empno, a.ename, a.job from emp a';

  -- Create the XML aus SQL
  l_xml := itstar_xml_util.sql2xml(l_sql_string);

  -- Display the XML
  dbms_output.put_line(l_xml.getclobval());

  l_json := itstar_xml_util.xml2json(l_xml);
  -- Display the JSON
  dbms_output.put_line(l_json.getclobval());  
end;

результат выглядит так:

{"ROWSET": [
    {
      "EMPNO": 7839,
      "ENAME": "KING",
      "JOB": "PRESIDENT"
    },
    {
      "EMPNO": 7698,
      "ENAME": "BLAKE",
      "JOB": "MANAGER"
    },
[...]
    {
      "EMPNO": 7934,
      "ENAME": "MILLER",
      "JOB": "CLERK"
    }
  ]}

поддержка Oracle 12c для JSON-это возможность хранить объекты JSON, запрашивать их и выбирать из них.

У вас есть табличный формат и нужно только отображать данные как JSON. Таким образом, вы можете просто объединить строки в {'col1': 'rowN1', 'col2': 'rowN2'} и сделать все остальное на стороне клиента. Или вы можете использовать LISTAGG для получения всего документа. Образец: http://technology.amis.nl/2011/06/14/creating-json-document-straight-from-sql-query-using-listagg-and-with-clause/

просто обратите внимание на ограничение SQL VARCHAR2 в 4000 символов.

вы также можете заглянуть в http://database-geek.com/2009/03/25/json-in-and-out-of-oracle-json-data-type/ но я не думаю, что тип объекта oracle улучшит вашу производительность.

еще один пример-экспорт XML с помощью XMLType. Затем преобразуйте XML в формат JSON. XMLType позаботится о специальных символах, а API довольно стабилен (вам не нужно будет переписывать свою программу для Oracle 14).


чтобы добавить ответ в oracle 12.2, вы можете создать json так, как хотите.

SELECT JSON_ARRAY(
JSON_OBJECT (
         KEY 'number' VALUE s.number,
         KEY 'name' VALUE s.sname,
         KEY 'location' VALUE s.loc
          )
       ) AS student_det
FROM   student s;

Я не вижу решения Python (в случае, если вам нужно сбросить JSON).

я писал JSON-ora-extract для экстрактов среднего размера (поскольку набор данных должен соответствовать доступной памяти).

Он использует wx_Oracle и json модули Python для чтения данных из базы данных Oracle (любой версии) и сброса в .

существует также возможность создания сжатого .