简体   繁体   English

Oracle XML 解析到表多个子元素

[英]Oracle XML Parse to Table Multiple Sub Elements

Hello I have an xml string I want to parse it to table.您好,我有一个 xml 字符串,我想将其解析为表格。 Problem is that when I have multiple sub categories in xml it throws exceptions.问题是,当我在 xml 中有多个子类别时,它会引发异常。

[Error] Execution (27: 35): ORA-19279: XPTY0004 - XQuery dynamic type mismatch: expected singleton sequence - got multi-item sequence [错误] 执行 (27: 35): ORA-19279: XPTY0004 - XQuery 动态类型不匹配:预期的单例序列 - 得到多项序列

MasaPersonelUrunleri, MasaPersonel can be more than one . MasaPersonelUrunleri,MasaPersonel 可以不止一个。 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  
;  

You could use chained XMLTable calls, but in this case you can make your XPath go down to the multi-element level:您可以使用链接的 XMLTable 调用,但在这种情况下,您可以使 XPath 下降到多元素级别:

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

db<>fiddle 数据库<>小提琴


The chained XMLTable approach would be something like:链式 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  
;  

where each XMLTable is producing some of the columns;其中每个 XMLTable 生成一些列; the multi-item sequence is the link between them, extracted from the first XMLTable and passed into the second.多项目序列是它们之间的链接,从第一个 XMLTable 中提取并传递给第二个。

db<>fiddle 数据库<>小提琴

PERSONEL varchar2(20) PATH './MASA/MasaPersonel/SICIL' causes problem when you have more than one MASA/MasaPersonel nodes当您有多个MASA/MasaPersonel节点时, PERSONEL varchar2(20) PATH './MASA/MasaPersonel/SICIL'会导致问题

That isn't shown in the sample in the question, but you can handle it with another chained XMLTable:这在问题的示例中没有显示,但您可以使用另一个链接的 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 数据库<>小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM