【发布时间】:2020-06-30 08:35:40
【问题描述】:
让我解释一下我的情况,您可能会更好地理解我的问题。我们需要从一组具有特定格式的表中创建一个 JSON 文件。我有使用 APEX_JSON 的想法,因为它很简单,但是我遇到了内存问题,因为 json 文档会生成 500 万条记录。实际上,当我通过应用 rownum 过滤器减少记录数时,该过程有效。但是,当查询尝试创建包含记录总数的json时,我得到了一个PL-SQL数字错误,这基本上是内存溢出。
我原来的JSON查询如下:
DECLARE
l_cursor SYS_REFCURSOR;
BEGIN
for l_hdr_row in (select FILENAME, REPORT_DATE, DOMAINCODE, LEGALENTITYCODE from RDM_OUT.JSON_NKEY_REP_HDR where DOMAINCODE = '00001')
loop
APEX_JSON.INITIALIZE_CLOB_OUTPUT;
APEX_JSON.OPEN_OBJECT;
APEX_JSON.OPEN_OBJECT(l_hdr_row.FILENAME);
APEX_JSON.OPEN_OBJECT;
APEX_JSON.WRITE('Date',l_hdr_row.REPORT_DATE);
APEX_JSON.WRITE('DomainCode',l_hdr_row.DOMAINCODE);
APEX_JSON.WRITE('LegalEntityCode',l_hdr_row.LEGALENTITYCODE);
APEX_JSON.OPEN_ARRAY('Keys');
FOR dtl IN (SELECT NATIVEKEY, MASTERKEY, ENDDATE
FROM RDM_OUT.JSON_NKEY_REP_DTL DTL
WHERE DTL.FILENAME = l_hdr_row.FILENAME) LOOP
APEX_JSON.OPEN_OBJECT;
APEX_JSON.WRITE('NativeKey',dtl.NATIVEKEY);
APEX_JSON.WRITE('MasterKey',dtl.MASTERKEY);
APEX_JSON.WRITE('EndDate',dtl.ENDDATE);
APEX_JSON.CLOSE_OBJECT;
END LOOP;
APEX_JSON.CLOSE_ARRAY;
APEX_JSON.CLOSE_OBJECT;
APEX_JSON.CLOSE_ALL;
DBMS_OUTPUT.PUT_LINE(APEX_JSON.GET_CLOB_OUTPUT);
APEX_JSON.FREE_OUTPUT;
end loop;
END;
/
第一个循环实际上只恢复了一行,这在第二个循环中得到了处理,在那里我得到了第一个循环中唯一出现的 550 万条记录。我尝试使用 JSON_OBJECT 和 JSON_ARRAY,但我无法获得 APEX_JSON 给我的相同输出格式。
我使用的是 Oracle 12.2,因此无法获得 18c 和 19c 中某些 JSON 函数的改进。
让我向您展示我使用 APEX_JSON 处理原始查询的结果
SQL> set serveroutput on size unlimited echo on timing on
SQL> DECLARE
2 l_cursor SYS_REFCURSOR;
BEGIN
3 4
5 for l_hdr_row in (select FILENAME, REPORT_DATE, DOMAINCODE, LEGALENTITYCODE from RDM_OUT.JSON_NKEY_REP_HDR where DOMAINCODE = '00001')
loop
6 7 8 APEX_JSON.INITIALIZE_CLOB_OUTPUT;
9 APEX_JSON.OPEN_OBJECT;
10 APEX_JSON.OPEN_OBJECT(l_hdr_row.FILENAME);
11
APEX_JSON.OPEN_OBJECT;
12 13 APEX_JSON.WRITE('Date',l_hdr_row.REPORT_DATE);
APEX_JSON.WRITE('DomainCode',l_hdr_row.DOMAINCODE);
14 15 APEX_JSON.WRITE('LegalEntityCode',l_hdr_row.LEGALENTITYCODE);
APEX_JSON.OPEN_ARRAY('Keys');
16 17
FOR dtl IN (SELECT NATIVEKEY, MASTERKEY, ENDDATE
FROM RDM_OUT.JSON_NKEY_REP_DTL DTL
18 19 20 WHERE DTL.FILENAME = l_hdr_row.FILENAME and rownum < 5 ) LOOP
APEX_JSON.OPEN_OBJECT;
APEX_JSON.WRITE('NativeKey',dtl.NATIVEKEY);
21 22 23 24 APEX_JSON.WRITE('MasterKey',dtl.MASTERKEY);
APEX_JSON.WRITE('EndDate',dtl.ENDDATE);
25 APEX_JSON.CLOSE_OBJECT;
END LOOP;
26 27 28 APEX_JSON.CLOSE_ARRAY;
APEX_JSON.CLOSE_OBJECT;
APEX_JSON.CLOSE_ALL;
29 30 31 32 DBMS_OUTPUT.PUT_LINE(APEX_JSON.GET_CLOB_OUTPUT);
APEX_JSON.FREE_OUTPUT;
end loop;
END;
33 34 35 36 /
{
"RTTA_00013_20190831_00001_00055_NKEY":{
{
"Date":"2019-08-31"
,"DomainCode":"
00001"
,"LegalEntityCode":"00055"
,"Keys":[
{
"NativeKey":"85430299"
,"MasterKey
":"01483175470"
,"EndDate":"9999-12-31"
}
,{
"NativeKey":"33227843"
,"MasterKey"
:"329401533000001934"
,"EndDate":"9999-12-31"
}
,{
"NativeKey":"42565570"
,"Mast
erKey":"01500329780"
,"EndDate":"9999-12-31"
}
,{
"NativeKey":"98536882"
,"Maste
rKey":"01502416501"
,"EndDate":"9999-12-31"
}
]
}
}
}
我的问题如下:
-
有没有更好的方法来做我正在用 APEX_JSON 做的事情?也许我可以以某种方式使用带有限制的 BULK COLLECT ?
-
如何使用 JSON_OBJECT 和 JSON_ARRAY 获得相同的结果和格式?我试过了,但我没有得到相同的输出格式。
谢谢大家!
【问题讨论】:
标签: sql oracle oracle-apex