gpt4 book ai didi

oracle - PL\SQL XMLTable 性能

转载 作者:行者123 更新时间:2023-12-02 00:58:15 25 4
gpt4 key购买 nike

我有一个函数可以解析 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 ;

如果我有一个小的 px_Block,这很有效。但我有一个情况,我可以有一个大的 XMLTYPE 并且这个函数需要很长时间。我是 XMLType 和 XMLTable 的新手。我可以做些什么来提高绩效吗?也许使用 BULK COLLECT 语句?

提前致谢,菲利普

编辑1:以下是仅适用于两个实例的 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>

编辑2:我对我的函数进行了一些更改,改进了 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 ;

最佳答案

XMLTABLE 的问题是 Oracle 使用 DOM Parser读取 XML。这意味着必须将整个 XML 加载到内存中,这会产生大量开销。看看DBMS_XMLSTORE 。该包使用 SAX Parser这是基于事件的(或基于流的)。

使用 SAX 解析器,您可以用普通 PC 读取大小为几 GB 的 XML 文件。

但是,直到 - 假设 50-100 MByte - DOM 解析器应该可以正常工作。

关于oracle - PL\SQL XMLTable 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33916475/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com