Oracle XML 解析表多个子元素
Posted
技术标签:
【中文标题】Oracle XML 解析表多个子元素【英文标题】:Oracle XML Parse to Table Multiple Sub Elements 【发布时间】:2020-07-01 18:18:21 【问题描述】:您好,我有一个 xml 字符串,我想将其解析为表。问题是当我在 xml 中有多个子类别时,它会引发异常。
[错误] 执行 (27: 35):ORA-19279: XPTY0004 - XQuery 动态类型不匹配:预期的单例序列 - 得到多项序列
MasaPersonelUrunleri, MasaPersonel 可以不止一个。当我在下面编写单个查询时,每个查询都有效,但是当我再添加一个元素时,它会引发错误。怎样才能解决问题?
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
;
【问题讨论】:
【参考方案1】:您可以使用链式 XMLTable 调用,但在这种情况下,您可以让您的 XPath 进入多元素级别:
select *
FROM XMLTABLE('/Masa/MASA/MasaPersonel/URUNLER/MasaPersonelUrunleri'
然后调整列路径以返回树:
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
;
得到:
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
db<>fiddle
链式 XMLTable 方法类似于:
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
;
每个 XMLTable 生成一些列的位置;多项目序列是它们之间的链接,从第一个 XMLTable 中提取并传递到第二个。
db<>fiddle
PERSONEL varchar2(20) PATH './MASA/MasaPersonel/SICIL'
在有多个MASA/MasaPersonel
节点时会导致问题
问题的示例中没有显示,但您可以使用另一个链接的 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
;
db<>fiddle
【讨论】:
PERSONEL varchar2(20) PATH './MASA/MasaPersonel/SICIL'
当您有多个 MASA/MasaPersonel
节点时会导致问题。
当然,但问题中没有显示这种情况。如果这是一个问题,那么它需要链中的另一个 XMLTable。以上是关于Oracle XML 解析表多个子元素的主要内容,如果未能解决你的问题,请参考以下文章