在oracle 12c中将sql查询的结果作为JSON返回

时间:2014-05-09 09:24:05

标签: json oracle oracle12c

背景

我需要从Oracle获取几千行并将它们转换为JSON以便在SlickGrid中使用。 目前我在PHP中获取行,使用iconv将其从ISO转换为UTF-8,并使用json_encode导出到json。数据库端整个操作大约需要1秒,生成JSON需要5秒。这是很长的路。

问题

我已经读过Oracle 12c支持JSON,但我找不到我需要的东西。

有没有办法以json格式返回标准sql查询的结果?

据说我想发出类似这样的查询:

SELECT * from table AS JSON

并收到与此类似的有效json:

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

重要的是我需要为我转义unicode序列,因为我在客户端使用ISO-8859-2字符集,而JSON必须是UTF-8或者有序列转义。< / p>

9 个答案:

答案 0 :(得分:15)

Oracle 12c 12.1.0.2版(自11.11.2014起的最新版本)增加了JSON支持: https://docs.oracle.com/database/121/NEWFT/chapter12102.htm#BGBGADCC

自10月17日起可以使用。 https://blogs.oracle.com/db/entry/oracle_database_12c_release_1

如果您无法修补/使用该版本,那么Lewis Cunningham和Jonas Krogsboell撰写的优秀软件包:PL / JSON * http://pljson.sourceforge.net/

这是一个很棒的软件包(我在很多数据库安装中都使用过它)。

包含的示例很好,涵盖了大多数情景。

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

答案 1 :(得分:7)

12cR2(Oracle云中提供)本机支持此功能。

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"}

答案 2 :(得分:4)

您可以使用xmltype将SQL的结果转换为XML和JSON。请参阅以下文章,了解从版本9开始适用于Oracle的解决方案。您还可以下载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"
    }
  ]}

答案 3 :(得分:1)

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对象类型会提高您的表现。

另一个方法是使用XMLType导出XML。然后将XML转换为JSON。 XMLType将处理特殊字符,API非常稳定(您不需要为Oracle 14重写程序)。

答案 4 :(得分:1)

要添加到oracle 12.2中的答案,您可以按照自己的意愿创建json。

item

答案 5 :(得分:1)

从Oracle 19c开始,该语法用于为表is simplified的行构造JSON表示形式

例如:要将wlink的所有行转换为单独的json,请使用

hr.employees

LIVE SQL example

答案 6 :(得分:1)

版本12.2包含用于直接从SQL查询生成JSON文档的新功能。实现目标的最简单方法是使用以下功能:JSON_OBJECTJSON_ARRAYAGG

create table tab as
    select level col1, 'value '||level col2 from dual connect by level <= 2
/ 

select max (rownum) rn, json_arrayagg (
    json_object (
        key 'col1' value col1,
        key 'col2' value col2
    ) format json returning clob 
) as json_doc
from tab;

结果:

        RN JSON_DOC                                                                        
---------- ---------------------------------------------------------
         2 [{"col1":1,"col2":"value 1"},{"col1":2,"col2":"value 2"}] 

使用大量数据进行测试:

select rn, length (json_doc) json_size, json_doc from (
    <query mentoined above here>
    cross join (select dummy from dual connect by level <= 1e5) 
    );

        RN  JSON_SIZE JSON_DOC                                                                        
---------- ---------- ---------------------------------------------------------
    200000    5600001 [{"col1":1,"col2":"value 1"},{"col1":2,"col2":"value 2"},

在慢速测试机上花费了大约1秒钟。创建5,6M JSON。


在版本19c中,函数JSON_OBJECT is simplified的语法。
上面的查询现在看起来像这样:

select json_arrayagg (  
    json_object (*) returning clob   
) as json_doc  
from tab;

Live SQL上。

答案 7 :(得分:0)

只需尝试一下:

:)生活很幸福

with data as
  ( select 
    xmlelement(e,regexp_replace('{"name":"'||colname||'"}', '[[:cntrl:]]', ''),',') col1
    from tblname
  )
  select
        rtrim(replace(replace(replace(xmlagg(col1).getclobval(),'&'||'quot;','"'),'<E>',''),'</E>',''),',')
        as very_long_json
  from data;

答案 8 :(得分:-1)

我没有看到Python解决方案(如果你需要转储JSON)。

我为中等大小的提取写了json-ora-extract(因为数据集必须符合可用内存)。

它使用OperationalError: (psycopg2.OperationalError) server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request. wx_Oracle Python模块从Oracle数据库(任何版本)读取数据并将其转储到json文件中。

还可以选择创建压缩的*.json文件。