从 PL/SQL 过程返回 CLOB 时是否需要使用 DBMS_LOB?

发布于 2024-08-08 21:57:30 字数 892 浏览 4 评论 0原文

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

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

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

酷遇一生 2024-08-15 21:57:30

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

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

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).

多像笑话 2024-08-15 21:57:30

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

(至少在Oracle 9中是这样,我相信在Oracle 10中性能差异更小。)

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.)

咋地 2024-08-15 21:57:30

我看不出你为什么要使用第二个。

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

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).

锦上情书 2024-08-15 21:57:30

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

如果您有一个名为“l_clob”的 CLOB 变量,并且执行类似“l_clob := l_clob || l_some_string_to_concatenate;”之类的操作,则在进行串联之前,它会将等式右侧的 l_clob 值转换为 VARCHAR2 ,可能会给您带来无效结果或错误。

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

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

寒冷纷飞旳雪 2024-08-15 21:57:30

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

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().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文