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

SWi*_*ilk 23 oracle json 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
Run Code Online (Sandbox Code Playgroud)

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

[{"col1": "value1", "col2": 2}, {"col1": "valueOfRow2", "col2": 3}]
Run Code Online (Sandbox Code Playgroud)

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

Ola*_*son 16

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;
/
Run Code Online (Sandbox Code Playgroud)

  • 12.1没有任何用于从关系数据生成JSON的功能。它只能解析现有的JSON数据。为此,您需要[Oracle 12.2](https://docs.oracle.com/database/122/ADJSN/changes.htm)。 (4认同)

mar*_*ake 9

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"]
Run Code Online (Sandbox Code Playgroud)

要么

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"}
Run Code Online (Sandbox Code Playgroud)


Kau*_*yak 8

从 Oracle 19c 开始,构建表行的 JSON 表示的语法得到简化

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

SELECT JSON_OBJECT(*) FROM hr.employees ;

{
"EMPLOYEE_ID" : 100,
"FIRST_NAME" : "Steven",
"LAST_NAME" : "King",
"EMAIL" : "SKING",
"PHONE_NUMBER" : "515.123.4567",
"HIRE_DATE" : "2003-06-17T00:00:00",
"JOB_ID" : "AD_PRES",
"SALARY" : 24000,
"COMMISSION_PCT" : null,
"MANAGER_ID" : null,
"DEPARTMENT_ID" : 90
}                       --row 1
{
"EMPLOYEE_ID" : 101,
"FIRST_NAME" : "Neena",
"LAST_NAME" : "Kochhar",
"EMAIL" : "NKOCHHAR",
"PHONE_NUMBER" : "515.123.4568",
"HIRE_DATE" : "2005-09-21T00:00:00",
"JOB_ID" : "AD_VP",
"SALARY" : 17000,
"COMMISSION_PCT" : null,
"MANAGER_ID" : 100,
"DEPARTMENT_ID" : 90
}                       --row 2
 ...
Run Code Online (Sandbox Code Playgroud)

实时 SQL 示例


0xd*_*xdb 7

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;
Run Code Online (Sandbox Code Playgroud)

结果:

        RN JSON_DOC                                                                        
---------- ---------------------------------------------------------
         2 [{"col1":1,"col2":"value 1"},{"col1":2,"col2":"value 2"}] 
Run Code Online (Sandbox Code Playgroud)

用大量数据测试:

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"},
Run Code Online (Sandbox Code Playgroud)

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


在 19c 版本中,函数的语法得到了JSON_OBJECT简化
上面的查询现在看起来像这样:

select json_arrayagg (  
    json_object (*) returning clob   
) as json_doc  
from tab;
Run Code Online (Sandbox Code Playgroud)

Live SQL 上


PT_*_*TAR 5

您可以使用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;
Run Code Online (Sandbox Code Playgroud)

结果看起来像这样:

{"ROWSET": [
    {
      "EMPNO": 7839,
      "ENAME": "KING",
      "JOB": "PRESIDENT"
    },
    {
      "EMPNO": 7698,
      "ENAME": "BLAKE",
      "JOB": "MANAGER"
    },
[...]
    {
      "EMPNO": 7934,
      "ENAME": "MILLER",
      "JOB": "CLERK"
    }
  ]}
Run Code Online (Sandbox Code Playgroud)