sql - 将 XMLTYPE 分块为 CLOB 时 XML 标记在中间中断
问题描述
我们有一个使用 SQL 编写 XML 文件的过程,我们被要求提高它的性能。目前,它像下面的代码一样逐行打印 XML:
begin
dbms_output.put_line('<tns:jpk>');
-- header section
for i in (select xmlelement("tns:header", header_num)
,xmlelement("tns:customer", customer_name)
,xmlelement("tns:po_number", po_number) li_xml
from header_tbl) loop
dbms_output.put_line( i.li_xml.getclobval() );
dbms_output.put_line('<tns:lines>');
-- Lines section
for x in (select xmlelement("tns:line_num", line_num)
,xmlelement("tns:order", order_dtl)
,xmlelement("tns:qty", qty)
from Lines_tbl) lx loop
dbms_output.put_line( x.lx_xml.getclobval() );
dbms_output.put_line('<tns:Summary>');
-- Summary section
for y in (select xmlelement("tns:sum_num", sum_num)
,xmlelement("tns:total_amt, total_amt)
,xmlelement("tns:total_qty, total_qty)
from Summary_Tbl) lc_xml loop
dbms_output.put_line( y.lc_xml.getclobval() );
end loop;
dbms_output.put_line('<tns:Summary>');
dbms_output.put_line('</tns:lines>');
end loop;
end loop;
dbms_output.put_line('</tns:jpk>');
end;
上面的示例代码如下所示:
<tns:jpk>
<tns:header>1</tns:header>
<tns:customer>1000</tns:customer>
<tns:po_number>909090</tns:po_number>
<tns:lines>
<tns:line_num>1</tns:line_num>
<tns:order>Other FA Open Asset Cost Pozostale Srodki Trwale -Wartosc poczatkowa</tns:order>
<tns:qty>1</tns:qty>
<tns:Summary>
<tns:sum_num>1</tns:sum_num>
<tns:total_amt>1000</tns:total_amt>
<tns:total_qty>1</tns:total_qty>
</tns:Summary>
</tns:lines>
</tns:jpk>
通过使用不同的方法,我设法使它更快一点,如下面的代码:
declare
xml_c xmltype;
procedure print_clob( p_clob in clob ) is
v_offset number := 1;
v_chunk_size number := 10000;
--v_chunk_size number := 32767;
begin
loop
exit when v_offset > dbms_lob.getlength(p_clob);
dbms_output.put_line( dbms_lob.substr( p_clob, v_chunk_size, v_offset ) );
v_offset := v_offset + v_chunk_size;
end loop;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('print_clob. others ' || SQLERRM);
end print_clob;
begin
select xmlagg(xmlconcat("<tns:jpk>",
-- header section
(select xmlagg(xmlconcat(
xmlelement("tns:header", header_num)
,xmlelement("tns:customer", customer_name)
,xmlelement("tns:po_number", po_number)
,xmlelement("tns:lines",
-- lines section
,(select
xmlagg(xmlconcat(
xmlelement("tns:line_num", line_num)
, xmlelement("tns:order", order_dtl)
, xmlelement("tns:qty", qty)
, (select
xmlagg(xmlconcat(
xmlelement("tns:sum_num", sum_num)
, xmlelement("tns:total_amt", total_amt)
, xmlelement("tns:total_qty", total_qty)))
from Summary_Tbl)
))
from Lines_tbl)
)
))
from header_tbl)
))
into xml_c
from dual;
print_clob( xml_c.getclobval );
end;
上面的代码生成了一个非常长的 XML,并将其分割并打印出来。根据执行时间,它可以正常工作且速度更快。然而,每当有一段很长的字符串时,输出有时会如下所示:
<tns:jpk>
<tns:header>1</tns:header>
<tns:customer>1000</tns:customer>
<tns:po_number>909090</tns:po_number>
<tns:lines>
<tns:line_num>1</tns:line_num>
<tns:order>Other FA Open Asset Cost Pozostale
Srodki Trwale -Wartosc poczatkowa</tns:order>
<tns:qty>1</tns:qty>
<tns:Summary>
<tns:sum_num>1</tns:sum_num>
<tns:total_amt>1000</tns:total_amt>
<tns:total_qty>1</tns:total_qty>
</tns:Summary>
</tns:lines>
</tns:jpk>
有没有办法让我在打印之前找出标签及其内容是否超出限制?
解决方案
推荐阅读
- javascript - 多个表头(头)行的问题
- c++ - 在 boost multi_index_container 中查找元素
- css - 我对 SVG 和谷歌字体“Monoton”有一个错误
- laravel - 如何在本地环境中的 vs 代码中使用 laravel 在 Vue 应用程序上实时重新加载?
- json - 根据类型跳过空值的序列化
- c# - 在解决方案文件夹中提供静态 pdf 文件 - 在 MVC 管道中,具有不同的路径
- angular - 如何将静态值输入动态 mat-table?
- postgresql - 不能在“set variable = ?”上使用参数化 声明,但硬编码有效
- python - 熊猫数据框与一些约束合并
- iframe - 计算机阻止 iframe 的显示