背景
我需要从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>
答案 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)
答案 6 :(得分:1)
版本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;
结果:
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
文件。