Domanda

Vorrei creare alcune procedure PL / SQL che restituiscono XML come parametri CLOB. Voglio solo fare questo (che funziona bene con test semplici):

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;

Ma ho accesso ad un altro codice sorgente che sostanzialmente fa questo:

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;

Mi chiedo se il primo metodo mi causerà problemi lungo la strada. Va bene farlo in quel modo? Qual è il vantaggio, se presente, del secondo metodo? Grazie!

È stato utile?

Soluzione

Penso che dovresti misurare le prestazioni di entrambi i metodi eseguendoli molte volte in un ciclo. Penso che le prestazioni siano l'unica differenza. Il blocco xml è breve ma quando si concatena un grande blocco xml è più veloce concatenare con dbms_low.writeappend rispetto all'utilizzo di ||.

(Almeno era in Oracle 9, credo che la differenza di prestazioni sia minore in Oracle 10.)

Altri suggerimenti

Ho eseguito le seguenti procedure per confrontare i tempi di esecuzione:

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

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

La differenza è neglible. Entrambi arrivano in circa 0,2 secondi in modo coerente.

Se cambio le procedure per passare a 999999 anziché a 10000, le prestazioni della versione 1 iniziano a diminuire leggermente (circa 39 secondi contro 32 secondi per la versione 2).

Non vedo alcun motivo per cui vorresti usare il secondo.

Se lv_xml era un VARCHAR2 anziché un CLOB, allora vedo un'ottima ragione (la lunghezza massima di una stringa letterale rispetto alla lunghezza massima di un CLOB).

Grazie per le risposte. Sulla base di ciò che ho letto sul sito elencato di seguito, suppongo che in realtà sia una buona cosa usare dbms_lob.writeappend. In caso contrario, potrei anche usare VARCHAR2s (che in alcuni casi non sarà abbastanza grande).

  

Se hai una variabile CLOB chiamata " l_clob " ;, e fai qualcosa del tipo " l_clob: = l_clob || l_some_string_to_concatenate; " ;, convertirà il valore l_clob sul lato destro dell'equazione in un VARCHAR2 prima di eseguire la concatenazione, dandoti possibilmente risultati non validi o un errore.

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

Esiste un'altra opzione che non menzionate: l'utilizzo della funzionalità XML integrata di Oracle (presumendo che abbiate una versione del database di 9i o successiva). Ad esempio, generare un documento XML da una query è uno snip con DBMS_XMLGEN.getXML () o DBMS_XMLGEN.getXMLType () .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top