mil*_*ros 4 oracle plsql xmltype
我有一个解析XMLTYPE变量的函数,对于每个消息,为XMLTYPE变量中的每个标记附加一个具有特定结构的CLOB.像这样:
FUNCTION myFunc (px_Header IN VARCHAR2,
px_Block IN XMLTYPE,
pn_numLines OUT PLS_INTEGER)
RETURN CLOB
IS
lcl_return CLOB := EMPTY_CLOB;
BEGIN
pn_numLines := 0;
FOR item
IN ( SELECT RPAD (NVL (RECEIPTNUMBER, ' '), 20) AS RECEIPTNUMBER,
RPAD (NVL (COMPANYCODE, ' '), 3) AS COMPANYCODE,
RPAD (NVL (BRAND, ' '), 3) AS BRAND,
RPAD (NVL (POLICYNUMBER, ' '), 20) AS POLICYNUMBER,
RPAD (NVL (CLAIMNUMBER, ' '), 20) AS CLAIMNUMBER,
RECEIPTAMOUNT
AS receiptAmount
FROM XMLTABLE (
'INT_DATA/Item'
PASSING px_Block
COLUMNS RECEIPTNUMBER VARCHAR2 (20)
PATH 'RECEIPTNUMBER',
COMPANYCODE VARCHAR2 (3)
PATH 'COMPANYCODE',
BRAND VARCHAR2 (3) PATH 'BRAND',
POLICYNUMBER VARCHAR2 (20)
PATH 'POLICYNUMBER',
CLAIMNUMBER VARCHAR2 (20)
PATH 'CLAIMNUMBER',
RECEIPTAMOUNT VARCHAR2 (15)
PATH 'RECEIPTAMOUNT'))
LOOP
lcl_return:=
lcl_return
|| px_Header
|| 'B2'
|| item.RECEIPTNUMBER
|| item.COMPANYCODE
|| item.BRAND
|| item.POLICYNUMBER
|| item.CLAIMNUMBER
|| item.RECEIPTAMOUNT
|| CHR (13)
|| CHR (10);
pn_numLines := pn_numLines + 1;
END LOOP;
RETURN lcl_return;
END myFunc ;
Run Code Online (Sandbox Code Playgroud)
如果我有一个小的,这很好用px_Block.但我有一个案例,我可以有一个大的XMLTYPE,这个功能需要很长时间.我是新用的XMLType和XMLTable.我能做些什么来提高性能.也许使用BULK COLLECT语句?
菲利普,提前谢谢
EDIT1:这是仅针对两个实例的XML示例.
<INT_DATA>
<Item>
<RECEIPTNUMBER>1</RECEIPTNUMBER>
<COMPANYCODE>148</COMPANYCODE>
<BRAND>006</BRAND>
<POLICYNUMBER>72972</POLICYNUMBER>
<CLAIMNUMBER>2015101504</CLAIMNUMBER>
<RECEIPTAMOUNT>-10.00</RECEIPTAMOUNT>
</Item>
<Item>
<RECEIPTNUMBER>1</RECEIPTNUMBER>
<COMPANYCODE>148</COMPANYCODE>
<BRAND>006</BRAND>
<POLICYNUMBER>73785</POLICYNUMBER>
<CLAIMNUMBER>2015101505</CLAIMNUMBER>
<RECEIPTAMOUNT>-22.50</RECEIPTAMOUNT>
</Item>
</INT_DATA>
Run Code Online (Sandbox Code Playgroud)
EDIT2:我的功能发生了一些变化,改进了20%.我改变了使用临时CLOB附加CLOB的方式.但更好的解决方案将会有所帮助.
FUNCTION myFunc (px_Header IN VARCHAR2,
px_Block IN XMLTYPE,
pn_numLines OUT PLS_INTEGER)
RETURN CLOB
IS
lcl_return CLOB := EMPTY_CLOB;
v_tmp_clob CLOB := EMPTY_CLOB;
BEGIN
pn_numLines := 0;
FOR item
IN ( SELECT RPAD (NVL (RECEIPTNUMBER, ' '), 20) AS RECEIPTNUMBER,
RPAD (NVL (COMPANYCODE, ' '), 3) AS COMPANYCODE,
RPAD (NVL (BRAND, ' '), 3) AS BRAND,
RPAD (NVL (POLICYNUMBER, ' '), 20) AS POLICYNUMBER,
RPAD (NVL (CLAIMNUMBER, ' '), 20) AS CLAIMNUMBER,
RECEIPTAMOUNT
AS receiptAmount
FROM XMLTABLE (
'INT_DATA/Item'
PASSING px_Block
COLUMNS RECEIPTNUMBER VARCHAR2 (20)
PATH 'RECEIPTNUMBER',
COMPANYCODE VARCHAR2 (3)
PATH 'COMPANYCODE',
BRAND VARCHAR2 (3) PATH 'BRAND',
POLICYNUMBER VARCHAR2 (20)
PATH 'POLICYNUMBER',
CLAIMNUMBER VARCHAR2 (20)
PATH 'CLAIMNUMBER',
RECEIPTAMOUNT VARCHAR2 (15)
PATH 'RECEIPTAMOUNT'))
LOOP
v_tmp_clob :=
TO_CLOB (px_Header)
|| TO_CLOB ('B2')
|| TO_CLOB (item.RECEIPTNUMBER)
|| TO_CLOB (item.COMPANYCODE)
|| TO_CLOB (item.BRAND)
|| TO_CLOB (item.POLICYNUMBER)
|| TO_CLOB (item.CLAIMNUMBER)
|| TO_CLOB (item.RECEIPTAMOUNT)
|| CHR (13)
|| CHR (10);
lcl_return := lcl_return || v_tmp_clob;
pn_numLines := pn_numLines + 1;
END LOOP;
RETURN lcl_return;
END myFunc ;
Run Code Online (Sandbox Code Playgroud)
问题XMLTABLE在于Oracle使用DOM Parser来读取XML.这意味着整个XML必须以很大的开销加载到内存中.看看DBMS_XMLSTORE.该软件包使用SAX Parser,它是事件库(或基于流).
使用SAX Parser,您可以使用普通PC读取大小为几千兆字节的XML文件.
但是,直到 - 比方说50-100 MByte - DOM解析器应该运行良好.
| 归档时间: |
|
| 查看次数: |
1539 次 |
| 最近记录: |