Hello I have an xml string I want to parse it to table. Problem is that when I have multiple sub categories in xml it throws exceptions.
[Error] Execution (27: 35): ORA-19279: XPTY0004 – XQuery dynamic type mismatch: expected singleton sequence – got multi-item sequence
MasaPersonelUrunleri, MasaPersonel can be more than one . When I write single every of them query below works but when I put one more element it throws error. How can solve the problem ?
select *
FROM XMLTABLE('/Masa'
PASSING
xmltype('
<Masa>
<ID>0</ID>
<SICIL>60950</SICIL>
<TARIH>2020-03-20T17:00:03</TARIH>
<IS_KERZZ>0</IS_KERZZ>
<MASA>
<MasaPersonel>
<SICIL>60950</SICIL>
<AD_SOYAD>Test User</AD_SOYAD>
<TOTAL>0</TOTAL>
<MASA_ID>0</MASA_ID>
<RESERVATION_ID>0</RESERVATION_ID>
<ID>0</ID>
<URUNLER>
<MasaPersonelUrunleri>
<ID>0</ID>
<ADET>1</ADET>
<BIRIM_FIYAT>20</BIRIM_FIYAT>
<SICIL>60950</SICIL>
<URUN_KOD>URN284</URUN_KOD>
<URUN_AD>IZGARA PİLİÇ</URUN_AD>
</MasaPersonelUrunleri>
<MasaPersonelUrunleri>
<ID>0</ID>
<ADET>1</ADET>
<BIRIM_FIYAT>25</BIRIM_FIYAT>
<SICIL>60950</SICIL>
<URUN_KOD>URN285</URUN_KOD>
<URUN_AD>TAVUK PİLİÇ</URUN_AD>
</MasaPersonelUrunleri>
</URUNLER>
</MasaPersonel>
</MASA>
</Masa>
')
COLUMNS
--describe columns and path to them:
SICIL varchar2(20) PATH './SICIL',
TARIH varchar2(20) PATH './TARIH',
PERSONEL varchar2(20) PATH './MASA/MasaPersonel/SICIL',
URUN_KODU varchar2(20) PATH './MASA/MasaPersonel/URUNLER/MasaPersonelUrunleri/URUN_KOD',
URUN_ADI varchar2(20) PATH './MASA/MasaPersonel/URUNLER/MasaPersonelUrunleri/URUN_AD',
URUN_ADETI number PATH './MASA/MasaPersonel/URUNLER/MasaPersonelUrunleri/ADET',
URUN_FIYATI number PATH './MASA/MasaPersonel/URUNLER/MasaPersonelUrunleri/BIRIM_FIYAT'
) xmlt
;
Advertisement
Answer
You could use chained XMLTable calls, but in this case you can make your XPath go down to the multi-element level:
select *
FROM XMLTABLE('/Masa/MASA/MasaPersonel/URUNLER/MasaPersonelUrunleri'
and then adjust the column paths to walk back up the tree:
COLUMNS
--describe columns and path to them:
SICIL varchar2(20) PATH './../../../../SICIL',
TARIH varchar2(20) PATH './../../../../TARIH',
PERSONEL varchar2(20) PATH './../../SICIL',
URUN_KODU varchar2(20) PATH 'URUN_KOD',
URUN_ADI varchar2(20) PATH 'URUN_AD',
URUN_ADETI number PATH 'ADET',
URUN_FIYATI number PATH 'BIRIM_FIYAT'
) xmlt
;
which gets:
SICIL TARIH PERSONEL URUN_KODU URUN_ADI URUN_ADETI URUN_FIYATI
-------------------- -------------------- -------------------- -------------------- -------------------- ---------- -----------
60950 2020-03-20T17:00:03 60950 URN284 IZGARA PİLİÇ 1 20
60950 2020-03-20T17:00:03 60950 URN285 TAVUK PİLİÇ 1 25
The chained XMLTable approach would be something like:
select xml1.SICIL, xml1.TARIH, xml1.PERSONEL, xml2.URUN_KODU, xml2.URUN_ADI, xml2.URUN_ADETI, xml2.URUN_FIYATI
FROM XMLTABLE('/Masa'
COLUMNS
--describe columns and path to them:
SICIL varchar2(20) PATH './SICIL',
TARIH varchar2(20) PATH './TARIH',
PERSONEL varchar2(20) PATH './MASA/MasaPersonel/SICIL',
URUNLERI xmltype PATH './MASA/MasaPersonel/URUNLER/MasaPersonelUrunleri'
) xml1
CROSS JOIN XMLTABLE ('/MasaPersonelUrunleri'
PASSING xml1.URUNLERI
COLUMNS
URUN_KODU varchar2(20) PATH './URUN_KOD',
URUN_ADI varchar2(20) PATH './URUN_AD',
URUN_ADETI number PATH './ADET',
URUN_FIYATI number PATH './BIRIM_FIYAT'
) xml2
;
where each XMLTable is producing some of the columns; the multi-item sequence is the link between them, extracted from the first XMLTable and passed into the second.
PERSONEL varchar2(20) PATH './MASA/MasaPersonel/SICIL'
causes problem when you have more than oneMASA/MasaPersonel
nodes
That isn’t shown in the sample in the question, but you can handle it with another chained XMLTable:
select xml1.SICIL, xml1.TARIH, xml2.PERSONEL, xml3.URUN_KODU, xml3.URUN_ADI, xml3.URUN_ADETI, xml3.URUN_FIYATI
FROM XMLTABLE('/Masa'
COLUMNS
--describe columns and path to them:
SICIL varchar2(20) PATH './SICIL',
TARIH varchar2(20) PATH './TARIH',
MASAPERSONEL xmltype PATH './MASA/MasaPersonel'
) xml1
CROSS JOIN XMLTABLE ('/MasaPersonel'
PASSING xml1.MASAPERSONEL
COLUMNS
PERSONEL varchar2(20) PATH './SICIL',
URUNLERI xmltype PATH './URUNLER/MasaPersonelUrunleri'
) xml2
CROSS JOIN XMLTABLE ('/MasaPersonelUrunleri'
PASSING xml2.URUNLERI
COLUMNS
URUN_KODU varchar2(20) PATH './URUN_KOD',
URUN_ADI varchar2(20) PATH './URUN_AD',
URUN_ADETI number PATH './ADET',
URUN_FIYATI number PATH './BIRIM_FIYAT'
) xml3
;