我想创建一些将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;

我想知道第一种方法是否会给我带来任何问题。这样做可以吗?如果有的话,对第二种方法有什么好处?谢谢!

有帮助吗?

解决方案

我认为你应该通过在循环中多次运行它们来测量两种方法的性能。我认为表现是唯一的区别。您的xml块很短,但是当您连接一个大的xml块时,使用dbms_low.writeappend连接比使用||更快。

(至少在Oracle 9中,我相信Oracle 10中的性能差异较小。)

其他提示

我运行了以下程序来比较执行时间:

版本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秒)。

我认为你没有理由想要使用第二个。

如果lv_xml是VARCHAR2而不是CLOB,那么我看到一个很好的理由(字符串文字的最大长度与CLOB的最大长度)。

感谢您的回答。根据我在下面列出的网站上阅读的内容,我将假设使用dbms_lob.writeappend实际上是一件好事。如果我不这样做,我可能也会使用VARCHAR2(在某些情况下它不够大)。

  

如果你有一个名为“l_clob”的CLOB变量,你会做类似“l_clob:= l_clob ||”的事情。 l_some_string_to_concatenate;&quot;,它会在进行连接之前将等式右边的l_clob值转换为VARCHAR2,可能会导致无效结果或错误。

http://www.maristream.org/srea/Huge_Strings_Using_LOBs.htm

您还没有提到另一个选项:使用Oracle的内置XML功能(假设您的数据库版本为9i或更高)。例如,从查询生成XML文档是使用 DBMS_XMLGEN.getXML() DBMS_XMLGEN.getXMLType()的剪辑。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top