Frage

Ich möchte einige PL / SQL-Prozeduren erstellen, die XML als CLOB-Parameter zurück. Ich möchte nur tun dies (die mit einfachen Tests gut funktioniert):

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;

Aber ich habe Zugang zu einem anderen Quellcode, der im Grunde tut dies:

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;

Ich frage mich, wenn die erste Methode für mich irgendwelche Probleme auf dem Weg führen wird. Ist es in Ordnung, es so zu tun? Was ist der Vorteil, wenn überhaupt, auf die zweite Methode? Dank!

War es hilfreich?

Lösung

Ich denke, man sollte die Leistung der beiden Methoden messen, indem sie viele Male in einer Schleife ausgeführt wird. Ich denke, die Leistung der einzige Unterschied ist. Ihr XML-Block ist kurz, aber wenn Sie einen großen XML-Block verketten ist es schneller verketten mit dbms_low.writeappend als der Verwendung von ||.

(zumindest war es in Oracle 9, glaube ich, der Performance-Unterschied kleiner in Oracle ist 10.)

Andere Tipps

Ich lief die folgenden Verfahren der Ausführungszeit vergleichen:

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;

Der Unterschied ist vernachlässigbar. Beide kommen in bei etwa 0,2 Sekunden konsequent.

Wenn ich die Verfahren Schleife 999999 statt 10000 ändern, Version 1 der Leistung beginnt etwas (ca. 39 Sekunden im Vergleich zu 32 Sekunden für version2) abzulehnen.

Ich sehe keinen Grund, warum Sie würde die zweite verwenden möchten.

Wenn lv_xml ein VARCHAR2 war eher als ein CLOB dann sehe ich einen sehr guten Grund (die maximale Länge eines Zeichenfolgenliterals gegen die maximale Länge eines CLOB).

Danke für die Antworten. Nach dem, was ich an der Stelle lesen Sie unten aufgeführt, ich gehe davon aus, dass es in der Tat ist eine gute Sache zu verwenden dbms_lob.writeappend. Wenn ich es nicht tun, könnte ich auch sein mit VARCHAR2s (die nicht groß genug, in einigen Fällen sein wird).

  

Wenn Sie ein CLOB-Variable namens „l_clob“ haben, und Sie tun so etwas wie „l_clob: = l_clob || l_some_string_to_concatenate;“, wird es den l_clob Wert auf der rechten Seite der Gleichung in einen VARCHAR2 konvertieren, bevor die Verkettung tun , möglicherweise ungültige Ergebnisse oder einen Fehler gibt.

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

Es ist eine weitere Option, die Sie erwähnen nicht: mit Oracle integrierte XML-Funktionalität (vorausgesetzt, Sie eine Datenbank-Version 9i oder höher). Zum Beispiel eines XML-Dokument aus einer Abfrage zu erzeugen ist ein Schnipsel mit DBMS_XMLGEN.getXML() oder DBMS_XMLGEN.getXMLType().

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top