PL / SQLプロシージャからCLOBを返すときにDBMS_LOBを使用する必要がありますか?

StackOverflow https://stackoverflow.com/questions/1613408

質問

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番目の方法には、もしあれば利点は何ですか?ありがとう!

役に立ちましたか?

解決

ループで何度も実行して、両方のメソッドのパフォーマンスを測定する必要があると思います。パフォーマンスが唯一の違いだと思います。 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秒で到着します。

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

2番目のものを使用する理由はわかりません。

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

回答ありがとうございます。以下にリストしたサイトで読んだ内容に基づいて、dbms_lob.writeappendを使用することが実際に良いことであると仮定します。そうでない場合は、VARCHAR2を使用することもあります(場合によっては十分な大きさではありません)。

  

&quot; l_clob&quot;というCLOB変数があり、&quot; l_clob:= l_clob || l_some_string_to_concatenate;&quot ;、連結を行う前に方程式の右側のl_clob値をVARCHAR2に変換し、無効な結果またはエラーが発生する可能性があります。

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top