我想创建一些将XML作为CLOB参数返回的PL / SQL过程。我想这样做(通过简单的测试可以正常工作):
create or replace procedure p_xml_test_1(
p_xml out nocopy clob
) is
begin
p_xml := '<?xml version="1.0" encoding="utf8" ?>' ||
'<test><something>some value</something></test>';
end p_xml_test_1;
但我可以访问其他基本上这样做的源代码:
create or replace procedure p_xml_test_2(
p_xml out nocopy clob
) is
lv_xml clob;
begin
dbms_lob.createtemporary(
lob_loc => p_xml,
cache => true
);
lv_xml := '<?xml version="1.0" encoding="utf8" ?>' ||
'<test><something>some value</something></test>';
dbms_lob.writeappend(
lob_loc => p_xml,
amount => length(lv_xml),
buffer => lv_xml
);
end p_xml_test_2;
我想知道第一种方法是否会给我带来任何问题。这样做可以吗?如果有的话,对第二种方法有什么好处?谢谢!
答案 0 :(得分:1)
我运行了以下程序来比较执行时间:
版本1
create or replace procedure p_xml_test_1(
p_xml out nocopy clob
) is
lv_i number;
begin
for lv_i in 1 .. 999999 loop
p_xml := p_xml || 'a';
end loop;
end p_xml_test_1;
第2版
create or replace procedure p_xml_test_2(
p_xml out nocopy clob
) is
lv_xml clob;
lv_i number;
begin
dbms_lob.createtemporary(
lob_loc => p_xml,
cache => true
);
for lv_i in 1 .. 999999 loop
lv_xml := 'a';
dbms_lob.writeappend(
lob_loc => p_xml,
amount => length(lv_xml),
buffer => lv_xml
);
end loop;
end p_xml_test_2;
差异可以忽略不计。两者都持续大约0.2秒。
如果我将程序更改为循环到999999而不是10000,则版本1的性能开始有所下降(约为39秒,而版本2为32秒)。
答案 1 :(得分:0)
我认为你应该通过在循环中多次运行它们来测量两种方法的性能。我认为表现是唯一的区别。您的xml块很短,但是当您连接一个大的xml块时,使用dbms_low.writeappend连接比使用||更快。
(至少在Oracle 9中,我相信Oracle 10中的性能差异较小。)
答案 2 :(得分:0)
我认为你没有理由想要使用第二个。
如果lv_xml是VARCHAR2而不是CLOB,那么我看到一个很好的理由(字符串文字的最大长度与CLOB的最大长度)。
答案 3 :(得分:0)
感谢您的回答。根据我在下面列出的网站上阅读的内容,我将假设使用dbms_lob.writeappend实际上是一件好事。如果我不这样做,我可能也会使用VARCHAR2(在某些情况下它不够大)。
如果你有一个名为“l_clob”的CLOB变量,并且执行类似“l_clob:= l_clob || l_some_string_to_concatenate;”的操作,它会在进行连接之前将等式右边的l_clob值转换为VARCHAR2 ,可能会给你无效的结果或错误。
答案 4 :(得分:0)
您还没有提到另一个选项:使用Oracle的内置XML功能(假设您的数据库版本为9i或更高)。例如,从查询生成XML文档是DBMS_XMLGEN.getXML()
或DBMS_XMLGEN.getXMLType()
的剪辑。