Skip to Main Content

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Mauro.

Asked: June 27, 2018 - 12:34 pm UTC

Last updated: July 13, 2018 - 9:00 am UTC

Version: 12c

Viewed 1000+ times

You Asked

hi all

i'm trying to make an enquiry from 2 tables with XML function, but i have some problems:

this is sql i'm using for this sample

select from the 2 different tables i'm using

select deptno,dname from dept;
select empno,ename,deptno from emp;


then i go to make the xml
SELECT XMLElement("Department",
                  dept_t(deptno,
                         edept,
                         cast(MULTISET
                              (SELECT empno, ename
                                 FROM emp e
                                 WHERE e.deptno = e.deptno)
                              AS emplist_t)))
  AS deptxml
  FROM dept d
  WHERE d.deptno = 10;


and i have a result

ORA-00902: tipo di dati non valido
00902. 00000 - "invalid datatype"
*Cause:
*Action:
Errore alla riga: 11, colonna: 34


except this error this is the kind of xml i'm trying to retrieve

<Department>
  <DEPT_T DEPTNO="10">
    <DNAME>ACCOUNTING</DNAME>
    <EMPLIST>
      <EMP_T EMPNO="7782">
        <ENAME>CLARK</ENAME>
      </EMP_T>
      <EMP_T EMPNO="7839">
        <ENAME>KING</ENAME>
      </EMP_T>
      <EMP_T EMPNO="7934">
        <ENAME>MILLER</ENAME>
      </EMP_T>
    </EMPLIST>
  </DEPT_T>
  <DEPT_T DEPTNO="20">
    <DNAME>ACCOUNTING2</DNAME>
    <EMPLIST>
      <EMP_T EMPNO="77821">
        <ENAME>CLARK2</ENAME>
      </EMP_T>
      <EMP_T EMPNO="78391">
        <ENAME>KING2</ENAME>
      </EMP_T>
      <EMP_T EMPNO="79341">
        <ENAME>MILLER2</ENAME>
      </EMP_T>
    </EMPLIST>
  </DEPT_T>
</Department>





but this is the only way to make a tree xml from more than one select?

thanks
Mauro


and Chris said...

I'm not sure why you need the subquery? You can join the two tables together and generate the XML that way.

Group by the columns that will appear at the department level and XMLAgg the employee information together:

set long 10000
with depts as (
  select xmlelement (
           "dept_t", xmlattributes (d.deptno),
           xmlelement ( 
             "emplist", xmlagg ( 
               xmlelement (
                 "emp_t", xmlattributes (e.empno),
                 xmlelement ( "ename", e.ename )
               )
             ) 
           )
         ) dept
  from   scott.dept d
  join   scott.emp e
  on     e.deptno = d.deptno
  where  d.deptno in (10, 20)
  group  by d.deptno
)
  select xmlserialize ( --for formatting the output
           content xmlelement (
             "department",
             xmlagg ( dept )
           ) as varchar2(1000)
           indent size = 2
         ) doc
  from   depts;

DOC                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
------------------------------------
<department>
  <dept_t DEPTNO="10">
    <emplist>
      <emp_t EMPNO="7782">
        <ename>CLARK</ename>
      </emp_t>
      <emp_t EMPNO="7934">
        <ename>MILLER</ename>
      </emp_t>
      <emp_t EMPNO="7839">
        <ename>KING</ename>
      </emp_t>
    </emplist>
  </dept_t>
  <dept_t DEPTNO="20">
    <emplist>
      <emp_t EMPNO="7369">
        <ename>SMITH</ename>
      </emp_t>
      <emp_t EMPNO="7902">
        <ename>FORD</ename>
      </emp_t>
      <emp_t EMPNO="7876">
        <ename>ADAMS</ename>
      </emp_t>
      <emp_t EMPNO="7788">
        <ename>SCOTT</ename>
      </emp_t>
      <emp_t EMPNO="7566">
        <ename>JONES</ename>
      </emp_t>
    </emplist>
  </dept_t>
</department>

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

need more in deep

Mauro Baratella, July 13, 2018 - 6:32 am UTC

Hi Chris
great work and this can works when there are only 2 tables to join, but if i have more than those 2 to group in a single XML?

i have to build this kind of xml

<?xml version="1.0" encoding="UTF-8" ?> 
<p:FatturaElettronica versione="FPR12" 
xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 
xmlns:p="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2 http://www.fatturapa.gov.it/export/fatturazione/sdi/fatturapa/v1.2/Schema_del_file_xml_FatturaPA_versione_1.2.xsd">
<FatturaElettronicaHeader>
<DatiTrasmissione>
<IdTrasmittente>
<IdPaese>IT</IdPaese> 
<IdCodice>01234567890</IdCodice> 
</IdTrasmittente>
<ProgressivoInvio>00001</ProgressivoInvio> 
<FormatoTrasmissione>FPR12</FormatoTrasmissione> 
<CodiceDestinatario>0000000</CodiceDestinatario> 
<PECDestinatario>betagamma@pec.it</PECDestinatario> 
</DatiTrasmissione>
<CedentePrestatore>
<DatiAnagrafici>
<IdFiscaleIVA>
<IdPaese>IT</IdPaese> 
<IdCodice>01234567890</IdCodice> 
</IdFiscaleIVA>
<Anagrafica>
<Denominazione>SOCIETA' ALPHA SRL</Denominazione> 
</Anagrafica>
<RegimeFiscale>RF01</RegimeFiscale> 
</DatiAnagrafici>
<Sede>
<Indirizzo>VIALE ROMA 543</Indirizzo> 
<CAP>07100</CAP> 
<Comune>SASSARI</Comune> 
<Provincia>SS</Provincia> 
<Nazione>IT</Nazione> 
</Sede>
</CedentePrestatore>
<CessionarioCommittente>
<DatiAnagrafici>
<CodiceFiscale>09876543210</CodiceFiscale> 
<Anagrafica>
<Denominazione>BETA GAMMA</Denominazione> 
</Anagrafica>
</DatiAnagrafici>
<Sede>
<Indirizzo>VIA TORINO 38-B</Indirizzo> 
<CAP>00145</CAP> 
<Comune>ROMA</Comune> 
<Provincia>RM</Provincia> 
<Nazione>IT</Nazione> 
</Sede>
</CessionarioCommittente>
</FatturaElettronicaHeader>
<FatturaElettronicaBody>
<DatiGenerali>
<DatiGeneraliDocumento>
<TipoDocumento>TD01</TipoDocumento> 
<Divisa>EUR</Divisa> 
<Data>2014-12-18</Data> 
<Numero>123</Numero> 
<Causale>LA FATTURA FA RIFERIMENTO AD UNA OPERAZIONE AAAA BBBBBBBBBBBBBBBBBB CCC DDDDDDDDDDDDDDD E FFFFFFFFFFFFFFFFFFFF GGGGGGGGGG HHHHHHH II LLLLLLLLLLLLLLLLL MMM NNNNN OO PPPPPPPPPPP QQQQ RRRR SSSSSSSSSSSSSS</Causale> 
<Causale>SEGUE DESCRIZIONE CAUSALE NEL CASO IN CUI NON SIANO STATI SUFFICIENTI 200 CARATTERI AAAAAAAAAAA BBBBBBBBBBBBBBBBB</Causale> 
</DatiGeneraliDocumento>
<DatiOrdineAcquisto>
<RiferimentoNumeroLinea>1</RiferimentoNumeroLinea> 
<IdDocumento>66685</IdDocumento> 
<NumItem>1</NumItem> 
</DatiOrdineAcquisto>
<DatiTrasporto>
<DatiAnagraficiVettore>
<IdFiscaleIVA>
<IdPaese>IT</IdPaese> 
<IdCodice>24681012141</IdCodice> 
</IdFiscaleIVA>
<Anagrafica>
<Denominazione>Trasporto spa</Denominazione> 
</Anagrafica>
</DatiAnagraficiVettore>
<DataOraConsegna>2012-10-22T16:46:12.000+02:00</DataOraConsegna> 
</DatiTrasporto>
</DatiGenerali>
<DatiBeniServizi>
<DettaglioLinee>
<NumeroLinea>1</NumeroLinea> 
<Descrizione>LA DESCRIZIONE DELLA FORNITURA PUO' SUPERARE I CENTO CARATTERI CHE RAPPRESENTAVANO IL PRECEDENTE LIMITE DIMENSIONALE. TALE LIMITE NELLA NUOVA VERSIONE E' STATO PORTATO A MILLE CARATTERI</Descrizione> 
<Quantita>5.00</Quantita> 
<PrezzoUnitario>1.00</PrezzoUnitario> 
<PrezzoTotale>5.00</PrezzoTotale> 
<AliquotaIVA>22.00</AliquotaIVA> 
</DettaglioLinee>
<DettaglioLinee>
<NumeroLinea>2</NumeroLinea> 
<Descrizione>FORNITURE VARIE PER UFFICIO</Descrizione> 
<Quantita>10.00</Quantita> 
<PrezzoUnitario>2.00</PrezzoUnitario> 
<PrezzoTotale>20.00</PrezzoTotale> 
<AliquotaIVA>22.00</AliquotaIVA> 
</DettaglioLinee>
<DatiRiepilogo>
<AliquotaIVA>22.00</AliquotaIVA> 
<ImponibileImporto>25.00</ImponibileImporto> 
<Imposta>5.50</Imposta> 
<EsigibilitaIVA>D</EsigibilitaIVA> 
</DatiRiepilogo>
</DatiBeniServizi>
<DatiPagamento>
<CondizioniPagamento>TP01</CondizioniPagamento> 
<DettaglioPagamento>
<ModalitaPagamento>MP01</ModalitaPagamento> 
<DataScadenzaPagamento>2015-01-30</DataScadenzaPagamento> 
<ImportoPagamento>30.50</ImportoPagamento> 
</DettaglioPagamento>
</DatiPagamento>
</FatturaElettronicaBody>
</p:FatturaElettronica>


this cannot be created from a single query

thanks
Mauro

Chris Saxon
July 13, 2018 - 9:00 am UTC

You can join as many tables as you want when using the XML* functions. It's just a matter of writing your query to fetch the data. Then calling the functions to construct your document as needed.

More to Explore

SQL

The Oracle documentation contains a complete SQL reference.