Dúvidas com criação de arquivo xml, com base em tabela

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

Pessoal,
Bom dia!
Pesquisei bastante nos tópicos de xml, porém não encontrei resposta pra minhas dúvidas!
1º) Preciso gerar um arquivo xml, com o resultado de uma consulta do oracle.
Esse primeiro passo já está OK, porém existem alguns campos que eu não tenho informação ( na tabela, ficam como null ) porém eu preciso dessa tag no arquivo.
Ao gerar via comando abaixo, ele simplismente ignora os campos nulos e não cria a tag que eu preciso.
Consegui ser claro na explicação da dúvida?

Selecionar tudo

create or replace procedure gerar_xml is

  v_file Utl_File.File_Type;
  v_xml  CLOB;

BEGIN
  DECLARE
  
    v_file Utl_File.File_Type;
    v_xml  CLOB;
    v_more BOOLEAN := TRUE;
  
    v_conteudo_arquivo sys.xmltype;
  
  BEGIN
    V_XML := DBMS_XMLQUERY.getXML('SELECT * FROM custom_xml');
   -- V_XML := DBMS_XMLGEN.getXMLType('SELECT * FROM custom_xml');
  
    V_FILE := UTL_FILE.fopen('C_RECEIVED_FILES', 'TESTE.XML', 'w');
  
    WHILE V_MORE LOOP
      UTL_FILE.PUT(V_FILE, SUBSTR(V_XML, 1, 32767));
    
      IF LENGTH(V_XML) > 32767 THEN
        V_XML := SUBSTR(V_XML, 32768);
      ELSE
        V_MORE := FALSE;
      END IF;
    END LOOP;
  
    UTL_FILE.fclose(V_FILE);
  
  EXCEPTION
    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(Substr(SQLERRM, 1, 255));
      Utl_File.FClose(v_file);
    
  END;

END;
2º) O cabeçalho do arquivo xml está sendo gerado da seguinte forma:
<?xml version = '1.0'?>
<ROWSET>

Como eu conseguiria alterar a tag "rowset" para um nome de minha preferência?

Obrigado desde já a todos! =)
Tinho
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 317
Registrado em: Seg, 16 Nov 2009 4:50 pm
Localização: São Paulo - SP

Bom dia,

Você já tentou utilizar o NVL. Será que ele não resolveria a sua primeira dúvida? Assim você poderia tratar o valor que está como nulo.

Quanto a outra questão, não sei se consegue alterar o cabeçalho. Vamos ver se algum outro colega do forum consegue ajudar.

Att.,
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

Infelizmente do jeito que você propôs dá erro ao gerar o xml.
As aspas estão finalizadas... rs
O comando ficou assim:

Selecionar tudo

    V_XML := DBMS_XMLQUERY.getXML('SELECT DT,NUMLINHA,SKU,NVL(UNID_MANEJO,' '),TESTE FROM custom_xml');

Segue msg em anexo de erro.

Selecionar tudo

<?xml version = '1.0'?>
<ERROR>oracle.xml.sql.OracleXMLSQLException: ORA-01756: string entre aspas não finalizada adequadamente
</ERROR>
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

Pessoal, tive um grande avanço na geração do arquivo e via select o resultado é aceitável. :)
Porém ao tentar inserir em uma váriavel xclob da erro em anexo:

Selecionar tudo

<?xml version = '1.0'?>
<ERROR>oracle.xml.sql.OracleXMLSQLException: ORA-00911: caractere inválido
</ERROR>
Abaixo segue o código que estou usando:

Selecionar tudo

create or replace procedure gerar_xml is

  v_file Utl_File.File_Type;
  v_xml  CLOB;

BEGIN
  DECLARE
  
    v_file Utl_File.File_Type;
    v_xml  CLOB;
    v_more BOOLEAN := TRUE;
  
  BEGIN
   v_xml:= DBMS_XMLQUERY.getXML('select xmlelement("Confirmacaoseparacao", 
                  xmlforest(teste1.clmcl,
                            teste1.codfilial,
                            teste1.dtcriacao,
                            teste1.atualizacao ),
                            xmlelement("OrdemCarga",
                            xmlforest(teste1.NumDoctoTrans),
                            xmlforest(teste1.NumOrdemCarga),
                            xmlforest(teste1.CodLocalSaida),
                            xmlforest(teste1.CodTransportadora),
                            xmlforest(teste1.NumRomaneio),
                            xmlforest(teste1.placaveiculo),
                xmlelement("Remessas",
                    xmlelement("Remessa",
                       xmlforest(teste1.numremessa),
                          xmlelement("Itens",
                            xmlelement("Item",
                            xmlforest(teste1.numlinha),
                            xmlforest(teste1.sku), 
                            xmlforest(teste1.quantidade),
                            xmlforest(teste1.unidmanejo),
                            xmlforest(teste1.deposito),
                            xmlforest(teste1.tipoestoque),
                             xmlelement("Lotes",
                                xmlelement("Lote",
                                xmlforest(teste1.numlote),
                                xmlforest(teste1.qtdlote)
               )
                )
                 )
                  )
                   )
                      )
                      )
                            )
  from custom_xml teste1;');

    V_FILE := UTL_FILE.fopen('C_RECEIVED_FILES', 'TESTE.XML', 'w');
  
    WHILE V_MORE LOOP
      UTL_FILE.PUT(V_FILE, SUBSTR(V_XML, 1, 32767));
    
      IF LENGTH(V_XML) > 32767 THEN
        V_XML := SUBSTR(V_XML, 32768);
      ELSE
        V_MORE := FALSE;
      END IF;
    END LOOP;
  
    UTL_FILE.fclose(V_FILE);
  
  EXCEPTION
    
    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(Substr(SQLERRM, 1, 255));
      Utl_File.FClose(v_file);
    
  END;

END;
Alguém sabe alguma solução? :)
Trevisolli
Moderador
Moderador
Mensagens: 2016
Registrado em: Qua, 12 Jan 2005 3:25 pm
Localização: Araraquara - SP
Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

Brother,

Tenta passar a função TO_CLOB pra ver se dá certo, na atribuição da variável:

Selecionar tudo

v_xml:= TO_CLOB(DBMS_XMLQUERY.getXML ... );
qualquer coisa, manda ai.
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

Trevisolli,
Fiz a sua sugestão, porém o erro persiste!
Segue a mensagem!

Selecionar tudo

<?xml version = '1.0'?>
<ERROR>oracle.xml.sql.OracleXMLSQLException: ORA-00911: caractere inválido
</ERROR>
Alguma outra idéia? :)
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR
Rafael O. Genaro

Já tentou tirar o ; dentro da query na linha abaixo?

Selecionar tudo

 from custom_xml teste1;'
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

rogenaro,
Já tentei sim, porém ele da o seguinte erro:

Selecionar tudo

<?xml version = '1.0'?>
<ERROR>oracle.xml.sql.OracleXMLSQLException: Caractere '(' não é permitido em um nome de tag XML.</ERROR>
já tentei utilizar a função to_clob porém sem sucesso também! :(
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

guterror escreveu:rogenaro,
Já tentei sim, porém ele da o seguinte erro:

Selecionar tudo

<?xml version = '1.0'?>
<ERROR>oracle.xml.sql.OracleXMLSQLException: Caractere '(' não é permitido em um nome de tag XML.</ERROR>
já tentei utilizar a função to_clob porém sem sucesso também! :(
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR
Rafael O. Genaro

Tenta colocar um alias para a coluna de retorno, provavelmente está sendo gerado um nome automaticamente com os primeiros caracteres da query, que inclui o caracter '('.
guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

Bom dia !!
Tentei da seguinte forma:

Selecionar tudo

   v_xml:= DBMS_XMLQUERY.getXML('SELECT B.* from (select xmlelement("ConfirmacaoSeparacao", 
                  xmlforest(Clmcl,
                            CodFilial,
                            DtCriacao,
                            Atualizacao ),
                            xmlelement("OrdemCarga",
                            xmlforest(NumDoctoTrans),
                            xmlforest(NumOrdemCarga),
                            xmlforest(CodLocalSaida),
                            xmlforest(CodTransportadora),
                            xmlforest(NumRomaneio),
                            xmlforest(PlacaVeiculo),
                xmlelement("Remessas",
                    xmlelement("Remessa",
                       xmlforest(NumRemessa),
                          xmlelement("Itens",
                            xmlelement("Item",
                            xmlforest(NumLinha),
                            xmlforest(Sku), 
                            xmlforest(Quantidade),
                            xmlforest(UnidManejo),
                            xmlforest(Deposito),
                            xmlforest(TipoEstoque),
                             xmlelement("Lotes",
                                xmlelement("Lote",
                                xmlforest(NumLote),
                                xmlforest(QtdLote)
               )
                )
                 )
                  )
                   )
                      )
                      )
                            )
  from xml_gene) b');
Porém sem sucesso!
Há alguma outra forma de estar gerando esse retorno em xml? =(
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR
Rafael O. Genaro

E desta forma, dá o mesmo erro?

Selecionar tudo

v_xml:= DBMS_XMLQUERY.getXML(
'
  select xmlelement
         ( "ConfirmacaoSeparacao"
         , xmlforest
           ( Clmcl
           , CodFilial
           , DtCriacao
           , Atualizacao 
           )
         , xmlelement
           ( "OrdemCarga"
           , xmlforest(NumDoctoTrans)
           , xmlforest(NumOrdemCarga)
           , xmlforest(CodLocalSaida)
           , xmlforest(CodTransportadora)
           , xmlforest(NumRomaneio)
           , xmlforest(PlacaVeiculo)
           , xmlelement
             ( "Remessas"
             , xmlelement
               ( "Remessa"
               , xmlforest(NumRemessa)
               , xmlelement
                 ( "Itens"
                 , xmlelement
                   ( "Item"
                   , xmlforest(NumLinha)
                   , xmlforest(Sku)
                   , xmlforest(Quantidade)
                   , xmlforest(UnidManejo)
                   , xmlforest(Deposito)
                   , xmlforest(TipoEstoque)
                   , xmlelement
                     ( "Lotes"
                     , xmlelement
                       ( "Lote"
                       , xmlforest(NumLote)
                       , xmlforest(QtdLote)
                       )
                     )
                   )
                 )
               )
             )
           )
         ) resultado
  from xml_gene' );

guterror
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 27
Registrado em: Qua, 03 Out 2012 3:29 pm

Rogenaro,
mesmo problema.
Oque eu fiz de solução foi inserir o conteúdo em uma tabela xml.type e pegar o retorno inteiro do resultado.
:D

Obrigado pela ajuda!
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Google Adsense [Bot] e 16 visitantes