Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Gerando XML PLSQL Iterativo


Não adianta tentar gerar XML muito grande em PL/SQL. O problema não é o PL/SQL como tal, mas o PL/SQL só suporta XML DOM, e o DOM não lida bem com XML grande. Você não diz o tamanho do documento XML que possui, mas não ficaria surpreso ao descobrir que a memória usada pelo PL/SQL para construir seu documento é cerca de 10 a 30 vezes o tamanho do documento resultante.

Existe uma opção para gerar o XML usando algo diferente de PL/SQL? Se não, e eu realmente tive que gerar grandes arquivos XML em um banco de dados Oracle, eu consideraria usar procedimentos armazenados Java. Esta pergunta tem algumas respostas sobre como fazer esse tipo de coisa em Java.

EDITAR em resposta ao seu comentário:seu código definitivamente não está escrevendo uma linha de cada vez. Ele está escrevendo o lote junto, fato que verifiquei executando-o usando a consulta SELECT * FROM all_objects no meu banco de dados Oracle 11g XE. O loop foi executado uma vez e escreveu 7.341 objetos, criando um arquivo XML com pouco mais de 3 MB de tamanho.

Em seguida, tentei modificar seu código para oferecer melhor suporte à abordagem 'incremental' que você descreve. Isso envolveu:

  • adicionando uma linha dbms_xmlgen.setmaxrows(ctx, max_rows); para dizer ao DBMS_XMLGEN para gerar apenas 5 linhas por vez. Caso contrário, ele tenta gerar o lote de uma só vez.

  • modificando o código na parte superior do WHILE loop para
    xml_result := dbms_xmlgen.getXML(ctx);
    num_rows_processed := DBMS_XMLGEN.GETNUMROWSPROCESSED(ctx);
    dbms_output.put_line('Got ' || num_rows_processed || ' rows processed');
    
    while num_rows_processed > 0
      -- rest of loop omitted
    

  • adicionando a primeira dessas três linhas antes da parte inferior do WHILE ciclo.

Em seguida, executei novamente seu código e pude vê-lo gravando cada lote de cinco linhas no arquivo a cada vez. No entanto, há um pequeno problema com essa abordagem, pois o arquivo foi substituído a cada vez. No final, eu tinha apenas um único registro no arquivo XML de saída. Eu não posso imaginar que isso seria o que você quer.

O WRITETOCLOB , WRITETOBUFFER e WRITETOFILE métodos em DBMS_XMLDOM não sugerem a capacidade de anexar a um arquivo existente e, para ser honesto, não estou surpreso que eles não o façam. Se você pudesse, acabaria com um XML inválido, pois haveria mais de um <?xml ... ?> declaração no arquivo.

Eu mantenho meu conselho anterior. Sempre que você precisar lidar com XML grande, em um banco de dados Oracle ou em outro lugar, use SAX ou StAX. PL/SQL também não suporta, então faça o que for necessário em procedimentos armazenados Java ou faça-o fora do banco de dados.