Pregunta

Me gustaría crear algunos procedimientos PL / SQL que devuelven XML como parámetros CLOB. Solo quiero hacer esto (que funciona bien con pruebas simples):

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;

Pero tengo acceso a otro código fuente que básicamente hace esto:

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;

Me pregunto si el primer método me causará problemas en el futuro. ¿Está bien hacerlo de esa manera? ¿Cuál es la ventaja, si la hay, para el segundo método? Gracias!

¿Fue útil?

Solución

Creo que debería medir el rendimiento de ambos métodos ejecutándolos muchas veces en un bucle. Creo que el rendimiento es la única diferencia. Su bloque xml es corto, pero cuando concatena un bloque xml grande, es más rápido concatenar con dbms_low.writeappend que utilizando ||.

(Al menos estaba en Oracle 9, creo que la diferencia de rendimiento es menor en Oracle 10)

Otros consejos

Ejecuté los siguientes procedimientos para comparar el tiempo de ejecución:

Versión 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;

Versión 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 diferencia es despreciable. Ambos vienen en alrededor de .2 segundos consistentemente.

Si cambio los procedimientos para pasar a 999999 en lugar de 10000, el rendimiento de la versión 1 comienza a disminuir un poco (aproximadamente 39 segundos frente a 32 segundos para la versión 2).

No veo ninguna razón por la que quieras usar la segunda.

Si lv_xml era un VARCHAR2 en lugar de un CLOB, veo una muy buena razón (la longitud máxima de un literal de cadena frente a la longitud máxima de un CLOB).

Gracias por las respuestas. De acuerdo con lo que leí en el sitio que se indica a continuación, voy a suponer que, de hecho, es algo bueno usar dbms_lob.writeappend. Si no lo hago, podría estar usando VARCHAR2s (que en algunos casos no será lo suficientemente grande).

  

Si tienes una variable CLOB llamada " l_clob " ;, y haces algo como " l_clob: = l_clob || l_some_string_to_concatenate; " ;, convertirá el valor de l_clob en el lado derecho de la ecuación a un VARCHAR2 antes de realizar la concatenación, posiblemente brindándole resultados no válidos o un error.

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

Hay otra opción que no mencionas: usar la funcionalidad XML integrada de Oracle (suponiendo que tienes una versión de base de datos de 9i o superior). Por ejemplo, generar un documento XML a partir de una consulta es un recorte con DBMS_XMLGEN.getXML () o DBMS_XMLGEN.getXMLType () .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top