Oracle XML Разбор в таблицу нескольких подэлементов - PullRequest
0 голосов
/ 20 марта 2020

Здравствуйте, у меня есть строка xml, которую я хочу проанализировать в таблице. Проблема заключается в том, что когда у меня несколько подкатегорий в xml, он генерирует исключения.

[Ошибка] Выполнение (27: 35): ORA-19279: XPTY0004 - XQuery dynamici c несоответствие типов: ожидаемая одноэлементная последовательность - получил последовательность из нескольких элементов

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 Ответ

1 голос
/ 20 марта 2020

Вы можете использовать цепочечные вызовы XMLTable, но в этом случае вы можете довести свой XPath go до многоэлементного уровня:

select *  
FROM XMLTABLE('/Masa/MASA/MasaPersonel/URUNLER/MasaPersonelUrunleri'  

, а затем настроить пути столбцов, чтобы вернуться к 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  
;  

, который получает:

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 создает некоторые из столбцов; последовательность из нескольких элементов - это связь между ними, извлеченная из первой таблицы XML и переданная во вторую.

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
;  

дб <> скрипка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...