Pergunta

Eu gostaria de criar alguns procedimentos PL / SQL que XML retorno como parâmetros CLOB. Quero apenas fazer isso (que funciona bem com testes 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;

Mas eu tenho acesso a algum outro código-fonte que faz basicamente isso:

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;

Eu estou querendo saber se o primeiro método irá causar quaisquer problemas para mim no caminho. É ok para fazê-lo dessa forma? Qual é a vantagem, se houver, para o segundo método? Obrigado!

Foi útil?

Solução

Eu acho que você deve medir o desempenho de ambos os métodos, executando-os muitas vezes em um loop. Eu acho que o desempenho é a única diferença. Seu bloco de xml é curta, mas quando você concatenar um bloco de xml grande que é mais rápido para concatenar com dbms_low.writeappend do que usar ||.

(pelo menos era no Oracle 9, acredito que a diferença de desempenho é menor no Oracle 10.)

Outras dicas

Eu corri os seguintes procedimentos para comparar o tempo de execução:

Versão 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;

A diferença é neglible. Ambos vêm em em cerca de 0,2 segundo de forma consistente.

Se eu mudar os procedimentos para loop para 999999 em vez de 10000, versão 1 de começos de desempenho a diminuir ligeiramente (cerca de 39 segundos versus 32 segundos para version2).

Eu não vejo nenhuma razão pela qual você gostaria de usar o segundo.

Se lv_xml era um VARCHAR2 em vez de um CLOB então eu vejo uma razão muito boa (o comprimento máximo de um literal de cadeia vs o comprimento máximo de um CLOB).

Obrigado pelas respostas. Com base no que eu li no site listado abaixo, eu vou assumir que é de fato uma coisa boa para uso dbms_lob.writeappend. Se eu não fizer isso, eu poderia muito bem estar usando VARCHAR2s (que não será grande o suficiente em alguns casos).

Se você tem uma variável CLOB chamado "l_clob", e você faz algo como "l_clob: = l_clob || l_some_string_to_concatenate;", ele irá converter o valor l_clob no lado direito da equação para um VARCHAR2 antes de fazer a concatenação , possivelmente dando-lhe resultados inválidos ou um erro.

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

Não há outra opção que você não mencionar: usando Oracle built-in funcionalidade XML (presumindo que você tem uma versão de banco de dados de 9i ou superior). Por exemplo, gerando um documento XML a partir de uma consulta é um recorte com DBMS_XMLGEN.getXML() ou DBMS_XMLGEN.getXMLType().

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top