开发者

Is use of DBMS_LOB necessary when returning CLOB from PL/SQL procedure?

I would like to create some PL/SQL procedures that return XML as CLOB parameters. I want to just do this (which works fine with simple tests):

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;

But I have access to some other source code that basically does this:

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;

I'm wondering if the first method will cause any problems for me down the road. Is it ok to do it that way? What is the advantage, if any开发者_开发技巧, to the second method? Thanks!


I ran the following procedures to compare execution time:

Version 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;

Version 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;

The difference is neglible. Both come in at around .2 seconds consistently.

If I change the procedures to loop to 999999 instead of 10000, version 1's performance starts to decline somewhat (about 39 seconds versus 32 seconds for version2).


I think you should measure the performance of both methods by running them many times in a loop. I think performance is the only difference. Your xml block is short but when you concatenate a big xml block it is faster to concatenate with dbms_low.writeappend than using ||.

(At least it was in Oracle 9, I believe the performance difference is smaller in Oracle 10.)


I see no reason why you'd want to use the second one.

If lv_xml was a VARCHAR2 rather than a CLOB then I see a very good reason (the max length of a string literal vs the max length of a CLOB).


Thanks for the answers. Based on what I read at the site listed below, I'm going to assume that it is in fact a good thing to use dbms_lob.writeappend. If I don't, I might as well be using VARCHAR2s (which won't be large enough in some cases).

If you have a CLOB variable called "l_clob", and you do something like "l_clob := l_clob || l_some_string_to_concatenate;", it will convert the l_clob value on the right side of the equation to a VARCHAR2 before doing the concatenation, possibly giving you invalid results or an error.

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


There is another option which you don't mention: using Oracle's built-in XML functionality (presuming you have a database version of 9i or higher). For instance, generating an XML document from a query is a snip with DBMS_XMLGEN.getXML() or DBMS_XMLGEN.getXMLType().

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜