2

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;

最初の方法で問題が発生するかどうかは疑問です。そんなことしていいの?2 番目の方法の利点は何ですか? ありがとう!

4

5 に答える 5

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 秒です。

手順を 10000 ではなく 999999 にループするように変更すると、バージョン 1 のパフォーマンスが多少低下し始めます (バージョン 2 の 32 秒に対して約 39 秒)。

于 2009-10-26T14:55:30.260 に答える
0

答えてくれてありがとう。以下のサイトで読んだ内容に基づいて、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

于 2009-10-24T11:15:05.720 に答える
0

両方のメソッドをループで何度も実行して、両方のメソッドのパフォーマンスを測定する必要があると思います。パフォーマンスだけが違いだと思います。xmlブロックは短いですが、大きなxmlブロックを連結する場合は、||を使用するよりもdbms_low.writeappendと連結する方が高速です。

(少なくともOracle 9では、パフォーマンスの違いはOracle 10の方が小さいと思います。)

于 2009-10-23T17:43:27.947 に答える
0

言及していない別のオプションがあります。Oracleの組み込みXML機能を使用することです(データベースバージョンが9i以降であると想定しています)。たとえば、クエリからXMLドキュメントを生成することは、DBMS_XMLGEN.getXML()またはを使用したスニップDBMS_XMLGEN.getXMLType()です。

于 2009-10-25T07:46:08.667 に答える
0

2番目のものを使用したい理由はわかりません。

lv_xml が CLOB ではなく VARCHAR2 である場合、非常に正当な理由 (文字列リテラルの最大長と CLOB の最大長) が分かります。

于 2009-10-23T18:03:01.760 に答える