Criar arquivo xml a partir de várias tabelas

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
dudu0566
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 74
Registrado em: Seg, 06 Ago 2007 3:59 pm
Localização: Campinas - SP
Eduardo Gomes

Boa tarde,
Gostaria de saber se é possível e como fazer a geração de um arquivo xml a partir de várias tabelas.
Dei um pesquisada, mas encontrei apenas com uma única tabela.

Exemplo do resultado que gostaria:

Selecionar tudo

<ARQUIVO>
	<SEÇÃO>
		<TABELA1>
			<CAMPO1>'VALOR'	</CAMPO1>
			<CAMPO2>'VALOR'</CAMPO2>
			<CAMPO3>'VALOR'</CAMPO3>
			..
		</TABELA1>
		<TABELA2>
			<CAMPO21>'VALOR'</CAMPO21>
			<CAMPO22>'VALOR'</CAMPO22>
			<CAMPO23>'VALOR'</CAMPO23>
			..
		</TABELA2>
		..
	</SEÇÃO>
	<SEÇÃO>
		<TABELA3>
			<CAMPO31>'VALOR'</CAMPO31>
			<CAMPO32>'VALOR'</CAMPO32>
			<CAMPO33>'VALOR'</CAMPO33>
			..
		</TABELA3>
		..
	</SEÇÃO>
</ARQUIVO>


Grato
rafaelfrocha
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 45
Registrado em: Qua, 31 Out 2007 9:30 am
Localização: Uberlândia
Rafael Rocha

Dudu,

E possível sim. Uma maneira de fazer isto é utilizar o XMLElement, XMLForest, XMLConcat do próprio Oracle. Ex:

Selecionar tudo

SELECT
   XMLElement("cabecalho",
	XMLForest(a.campo1 as "campo1",
                        a.campo2 as "campo2",
                        b.campo3 as "campo3" )
                      )
FROM tabela a, tabela b
Tem outras formas de gerar XML. Acho esta flexível pois você tem a liberdade grande para montar um select.
dudu0566
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 74
Registrado em: Seg, 06 Ago 2007 3:59 pm
Localização: Campinas - SP
Eduardo Gomes

Valeu Rafael

Vou tentar usando seu exemplo......

Qualquer coisa posto o resultado.....


Abraços
dudu0566
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 74
Registrado em: Seg, 06 Ago 2007 3:59 pm
Localização: Campinas - SP
Eduardo Gomes

Então seguindo a dica do Rafael, fiz mais algumas pesquisas, e cheguei no seguinte código:

Selecionar tudo

select xmlelement("empresa"
		 ,xmlattributes(empresa.codigo as codigo)
		 ,xmlforest(empresa.nome as nome
		    	     ,empresa.cnpj as cnpj)
		 ,xmlelement("empresa-end"
					    	    ,(select xmlagg (xmlconcat(
				    		    xmlelement("endereço",empresa2.endereço)
				    		    ,xmlelement("bairro",empresa2.bairro)
					    	    ,xmlelement("cidade",empresa2.cidade)
					    	    ,xmlelement("estado",empresa2.estado)
					    	    ,xmlelement("cep",empresa2.cep)
                                                      )
                                            )
                               from t_teste_xml_empresa empresa2
                              where empresa.codigo = empresa2.codigo)
                            )
		 ,xmlelement("produto"
                            ,(select xmlagg(xmlelement("item",prod.descricao))
                                from fis.t_teste_xml_produto prod
                               where empresa.codigo = prod.cod_empresa)
                            )
		) xml
from t_teste_xml_empresa empresa
Como resultado, obtive:

Selecionar tudo

<empresa CODIGO="1">
	<NOME>Empresa</NOME>
	<CNPJ>1234567890123</CNPJ>
		<empresa-end>
			<endereço>Rua do Cobre, 745</endereço>
			<bairro>Brasilopis</bairro>
			<cidade>Brasilia</cidade>
			<estado>DF</estado>
			<cep>19647001<cep>
		</empresa-end>
	<produto>
		<item>Caixa de Papelão</item>
		<item>Tubo Plástico</item>
		<item>Rolo</item>
		<item>Caixote de Madeira</item>
		<item>Caixa de Aço</item>
	</produto>
</empresa>
Gostaria de saber, se há alguma maneira para que na "seção" produto conseguisse fazer como foi feito com empresa, "quebrando" para cada produto uma série de atributos:

Selecionar tudo

...
<item CODIGO="1">
<descrição>Caixa de Papelão</descrição>
<peso>12</peso>
...
</item>
...
Alguém tem alguma idéia???

Grato
rafaelfrocha
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 45
Registrado em: Qua, 31 Out 2007 9:30 am
Localização: Uberlândia
Rafael Rocha

Eduardo,
Tem como fazer sim! Procure utilizar um XMLElement para Item e para os atributos você pode utilizar um XMLForest ou até mesmo outros XMLElements!

Testa aí e vê se dá certo!
e_muniz
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 19
Registrado em: Qua, 01 Jul 2009 10:35 am
Localização: Belo Horizonte / MG

Senhores, criei as duas tabelas com os mesmos campos apresentados no exemplo anterior, porém ao tentar executar me retornou o seguinte errro:

"PL/SQL: ORA-00932: tipos de dados inconsistentes: esperava NUMBER obteve -"

Alguém tem alguma solução para isto??
rafaelfrocha
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 45
Registrado em: Qua, 31 Out 2007 9:30 am
Localização: Uberlândia
Rafael Rocha

posta seu código aí como exemplo...
dudu0566
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 74
Registrado em: Seg, 06 Ago 2007 3:59 pm
Localização: Campinas - SP
Eduardo Gomes

Mais uma dúvida, usando xmlelement, xmlattibute, ...... como eu escrevo um prefixo em alguma tag????


alias, alguém já desenvolveu alguma rotina pra desenvolver nfe??? se sim, tem como postar pra galera??


abraços
rafaelfrocha
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 45
Registrado em: Qua, 31 Out 2007 9:30 am
Localização: Uberlândia
Rafael Rocha

Eduardo,

o que você quer dizer com prefixo da Tag? nome da tag (<nome_tag>)? atributo (<tag atributo=xxx>)?

Quanto a NFe desenvolvemos aqui na empresa, praticamente tudo em PL/SQL, e o que não é PL/SQL é java e fica dentro do banco!

Infelizmente não posso postar os códigos por tratar de propriedade intelectual da empresa, mais se for do seu interesse posso lhe mandar uma apresentação deste módulo! Ele é integrável com sistemas ERP...
dudu0566
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 74
Registrado em: Seg, 06 Ago 2007 3:59 pm
Localização: Campinas - SP
Eduardo Gomes

Fala Rafael....

era o atributo...resolvi com o xmlattributes......

se tiver como você mandar a apresentação eu agradeceria.......
duardogomes@gmail.com


grato
e_muniz
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 19
Registrado em: Qua, 01 Jul 2009 10:35 am
Localização: Belo Horizonte / MG

Boa tarde Rafael,

Mesmo com a tentativa anterior de pedir o código da sua solução de NFe, e sua resposta negativa (é obvio), gostaria de pedir se é possível você. mencionar a forma de conexão utilizada para acessar os WS da sefaz..

Um abraço

Ernandes Muniz
rafaelfrocha
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 45
Registrado em: Qua, 31 Out 2007 9:30 am
Localização: Uberlândia
Rafael Rocha

Ernandes,

Para desenvolver os webservices, fizemos em java, e em seguida importamos suas respectivas classes no Oracle.

Procedimentos PL/SQL acessam as classes Java que comunicam com o SEFAZ..
leandromiranda87
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 43
Registrado em: Ter, 20 Mar 2012 11:37 am
Localização: Campinas
Leandro L. Miranda

Pessoal,

Estou com problemas para inserir o código XML em uma variável do tipo CLOB,

Selecionar tudo

DECLARE

  v_file Utl_File.File_Type;
  v_xml CLOB;
  v_more BOOLEAN := TRUE;
  
  v_error_code NUMBER := 0;
  v_error_text VARCHAR2(300) := '';
BEGIN
  V_XML := DBMS_XMLQUERY.getXML('SELECT
                                    XMLELEMENT("ROWSET",
                                    XMLELEMENT("ROW",
                                               XMLFOREST(CTX.WAREHOUSE_CODE AS "WAREHOUSE_CODE",
                                                         CTX.RECEPTION_CODE AS "RECEPTION_CODE",
                                                         CTX.REG_REC_ORDER AS "REG_REC_ORDER",
                                                         CTX.RECEPTION_STATUS_CODE AS "RECEPTION_STATUS_CODE", 
                                                         CTX.CONTAINERS_RECEIVED AS "CONTAINERS_RECEIVED",
                                                         CTX.DOOR_CODE AS "DOOR_CODE",
                                                         CTX.TYPE_CODE AS "TYPE_CODE",
                                                         CTX.CREATION_DATE AS "CREATION_DATE",
                                                         CTX.UPDATE_DATE AS "UPDATE_DATE",
                                                         CTX.SYSDATE_REG AS "SYSDATE_REG",
                                                         CTX.LINE_COUNT AS "LINE_COUNT"
                                                         ),
                                      XMLELEMENT(REG_LINES,
                                      XMLELEMENT(REG_LINES_ROW,
                                                 XMLFOREST(CTX.PRODUCT_CODE AS "PRODUCT_CODE",
                                                            CTX.QTTY_TO_RECEIVE_BASE AS "QTTY_TO_RECEIVE_BASE",
                                                            CTX.QTTY_TO_RECEIVE_UOM AS "QTTY_TO_RECEIVE_UOM",
                                                            CTX.UOM_CODE AS "UOM_CODE",
                                                            CTX.QTTY_RECEIVED_BASE AS "QTTY_RECEIVED_BASE",
                                                            CTX.QTTY_RECEIVE_UOM AS "QTTY_RECEIVE_BASE",
                                                            CTX.DETAIL_COUNT AS "DETAIL_COUNT",
                                                            CTX.LOT_COUNT AS "LOT_COUNT"),
                                        XMLELEMENT("REG_DETAILS", 
                                        XMLELEMENT("REG_DETAILS_ROW",
                                                   XMLFOREST(CTX.RECEPTION_STOCK_ID AS "RECEPTION_STOCK_ID",
                                                             CTX.CONTAINER_NO AS "CONTAINER_NO",
                                                             CTX.STOCK_QUANTITY AS "STOCK_QUANTITY",
                                                             CTX.STOCK_RECEPTION_DATE AS "STOCK_RECEPTION_DATE",
                                                             CTX.STOCK_WEIGHT AS "STOCK_WEIGHT"
                                                            )
                                                   )
                                                   )
                                                 )
                                                 )
                                               )
                                               )
                                    --INTO V_XML
                                    FROM CUSTOM_TESTE_XML CTX;');

  
  V_FILE := UTL_FILE.fopen('D_SENDED_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);
    
    v_error_code := SQLCODE;
    v_error_text := SUBSTR(SQLERRM, 1, 300);
      
END;

Como é possível ver, aproveito o mesmo processo pra salvar o resultado em um arquivo no diretório, mas o arquivo retorna o erro abaixo:

Selecionar tudo

<?xml version = '1.0'?>
<ERROR>oracle.xml.sql.OracleXMLSQLException: ORA-00911: caractere inválido
</ERROR>
Já tentei utilizar VARCHAR2(4000), mas tenho o mesmo problema.

Alguém sabe me dizer onde está meu erro??

Obrigado,
leandromiranda87
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 43
Registrado em: Ter, 20 Mar 2012 11:37 am
Localização: Campinas
Leandro L. Miranda

Segue também os dados que a tabela contém:

Selecionar tudo

WAREHOUSE_CODE: 01
RECEPTION_CODE: RCP169
REG_REC_ORDER:   
RECEPTION_STATUS_CODE: CLOSE
CONTAINERS_RECEIVED: 0000000001
DOOR_CODE: MUREC
TYPE_CODE: P
CREATION_DATE: 20110525093646
UPDATE_DATE: 20110525093745
SYSDATE_REG: 20110525093756
LINE_COUNT: 0000000001
PRODUCT_CODE: B003
QTTY_TO_RECEIVE_BASE: 000000800000
QTTY_TO_RECEIVE_UOM: 000000800000
UOM_CODE: UN
QTTY_RECEIVED_BASE: 0000800000
QTTY_RECEIVE_UOM: 0000800000
DETAIL_COUNT: 0000000001
LOT_COUNT: 0000000000
RECEPTION_STOCK_ID: 20581
CONTAINER_NO: 169000
STOCK_QUANTITY: 000000800000
STOCK_RECEPTION_DATE: 20110525000000
STOCK_WEIGHT: 000000000000
Estes dados foram lidos de um arquivo XML e inseridos nessa tabela, mas não estou conseguindo fazer o contrário. (leitura da tabela salvando em um arquivo XML)

Vlw,
marlonpasquali
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 248
Registrado em: Sex, 06 Fev 2009 3:02 pm
Localização: ERECHIM - RS

Amigos,
tentei rodar um exemplo destes para gerar XML e deu este erro:
ERRO:

Selecionar tudo

OCI-22303: tipo "SYS"."XMLTYPE" não encontrado
meu banco é:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production

Tem que instalar alguma coisa para estes comando para gerar arquivos XML funcionarem?
o exemplo que tentei rodar foi:

Selecionar tudo

SQL*Plus: Release 8.0.6.0.0 - Production on Qua Abr 11 11:12:57 2012
(c) Copyright 1999 Oracle Corporation.  All rights reserved.
Conectado a:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> SELECT
  2     XMLElement("cabecalho",
  3     XMLForest(a.customer_id as "campo1",
  4                          a.customer_name as "campo2",
  5                          b.trx_number as "campo3" )
  6                        )
  7  FROM ra_customers a,
  8       ra_customer_trx_all b
  9  where trunc(b.trx_date) = trunc(sysdate)
 10  and b.sold_to_customer_id = a.customer_id
 11  /
ERRO:

Selecionar tudo

OCI-22303: tipo "SYS"."XMLTYPE" não encontrado
leandromiranda87
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 43
Registrado em: Ter, 20 Mar 2012 11:37 am
Localização: Campinas
Leandro L. Miranda

Pessoal,

Tive algum avanço, mas continuo com problemas :(

Ao invés de fazer a seleção direto nesse processo, faço a inserção do resultado em uma variável xmltype em uma tabela

Selecionar tudo

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 conteudo_arquivo FROM custom_xml_received WHERE nome_arquivo = ' || q'['TESTE.XML']');
  --V_XML := DBMS_XMLGEN.getXMLType('SELECT conteudo_arquivo FROM custom_xml_received WHERE nome_arquivo = ' || q'['TESTE.XML']');
  
  V_FILE := UTL_FILE.fopen('D_SENDED_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;
Esse processo gera o arquivo, porém incompleto: (esse é o arquivo inteiro)

Selecionar tudo

<?xml version = '1.0'?>
<ROWSET>
   <ROW num="1">
      <CONTEUDO_ARQUIVO>
Durante a execução do procedimento o resultado retornado também é falho, como pode ser visto na imagem
Resultado retornado
Resultado retornado
Segue também a lista de erros que me retorna esse processo:
Erros retornados
Erros retornados
1.JPG (14.49 KiB) Exibido 44529 vezes
Alguém já passou por isso? ou saiba como solucionar?

Obrigado,
leandromiranda87
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 43
Registrado em: Ter, 20 Mar 2012 11:37 am
Localização: Campinas
Leandro L. Miranda

@marlonpasquali

Já verificou se essa type existe?
Users > SYS > OBJECTS > TYPES > XMLTYPE

se ela existir, poder que o usuário que você esteja usando não tenha permissão para acessar ela.
Se for isso, então terá que dar permissão para esse usuário, usando os GRANTs

Abs.
marlonpasquali
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 248
Registrado em: Sex, 06 Fev 2009 3:02 pm
Localização: ERECHIM - RS

Leandro, este type existe. Acho que Grant mesmo...

seria assim?

Selecionar tudo

GRANT EXECUTE ON TYPE::SYS.XMLTYPE 
    TO APPS WITH GRANT OPTION;
APPS seria o usuario que estou usando.

obrigado,
Marlon
leandromiranda87
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 43
Registrado em: Ter, 20 Mar 2012 11:37 am
Localização: Campinas
Leandro L. Miranda

Esta correto sim.

Selecionar tudo

GRANT EXECUTE ON TYPE::SYS.XMLTYPE 
TO APPS WITH GRANT OPTION;
Lembrando que esse processo deve ser feito com o usuário SYS.

http://ss64.com/ora/grant.html
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 4 visitantes