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)
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)
从 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)
12.2 版包括直接从 SQL 查询生成 JSON 文档的新功能。实现目标的最简单方法是使用函数:JSON_OBJECT
和JSON_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)
您可以使用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)
归档时间: |
|
查看次数: |
67542 次 |
最近记录: |