#sql #xml #oracle
#sql #xml #Oracle
Вопрос:
Я работаю с базой данных Oracle 19c.
У меня есть таблица с полем большого двоичного объекта «MSG_BODY». Это поле содержит XML-файлы, подобные этому:
<Body xmlns = "http://www.finnova.ch/ZV/EHF/021">
<Auftrag>
<Auftragsinformation>
<Auftragsidentifikation>
<AUF_LNR>987987987987</AUF_LNR>
<APPL_ID>9999</APPL_ID>
</Auftragsidentifikation>
<Auftragsreferenz>
<EXT_REF>TEST-2020082109574181</EXT_REF>
<EXT_AUF_REF>BA18081508D86B28</EXT_AUF_REF>
<KD_LNR_ERF>901</KD_LNR_ERF>
</Auftragsreferenz>
</Auftragsinformation>
<Zahlungsliste>
<Zahlung>
<Identifikation>
<ZV_ZLG_SYS_LNR>987987987987</ZV_ZLG_SYS_LNR>
<ZV_ZLG_LNR>1</ZV_ZLG_LNR>
</Identifikation>
<Referenz>
<EXT_REF>ABCD654654654</EXT_REF>
<EXT_REF_AUF>XX-XXX 230/99999/1</EXT_REF_AUF>
<EXT_REF_AUF_IB>BA9999988888</EXT_REF_AUF_IB>
<ZLG_INSTR_ID>BA999988886666</ZLG_INSTR_ID>
<MeldungsRef>
<MSG_TX_ID>123123123123</MSG_TX_ID>
<CS_ZLG_TRACK_ID>d8047b9f-a8c7-4d74-b5c7-470510240b60</CS_ZLG_TRACK_ID>
<CS_SWIFTGPI_SVC_ID>001</CS_SWIFTGPI_SVC_ID>
</MeldungsRef>
<MeldungsRef>
<MSG_TX_ID_DECK>xxxxxxxxxx</MSG_TX_ID_DECK>
</MeldungsRef>
</Referenz>
<Mitteilung>
<MIT_BEGxxx</MIT_BEG>
<MIT_BEG_XML>
<Ustrd>xxx</Ustrd>
</MIT_BEG_XML>
<PURP_CD>SALA</PURP_CD>
</Mitteilung>
</Zahlung>
</Zahlungsliste>
</Auftrag>
Тег «Zahlung» может существовать несколько раз, и это нормально, но в тег «Zahlung» входит
тег «MeldungsRef». Этот тег должен существовать ноль или один раз для каждого тега «Zahlung». Это ошибка, показанная в приведенном выше XML. Теперь мне нужен запрос для выбора всех строк в таблице, которая содержит XML, где тег «MeldungsRef» встречается там несколько раз. Как я могу это сделать?
Спасибо, что помогли мне!
С уважением, mablaser
Комментарии:
1. Это то, что вы запрашиваете для целей проверки xml? В этом случае было бы лучше зарегистрировать XML-схему
Ответ №1:
Вы ищете второе отображение MeldungsRef
узла внутри Zahlung
узла, поэтому вы можете искать непосредственно это. Этот запрос показывает вам первый и второй экземпляры узла, используя xmlquery()
и указывая внешний вид для поиска с помощью [1]
или [2]
:
select id,
xmlquery(
'declare default element namespace "http://www.finnova.ch/ZV/EHF/021"; (: :)
/Body/Auftrag/Zahlungsliste/Zahlung/Referenz/MeldungsRef[1]'
passing xmltype(msg_body)
returning content
) as first,
xmlquery(
'declare default element namespace "http://www.finnova.ch/ZV/EHF/021"; (: :)
/Body/Auftrag/Zahlungsliste/Zahlung/Referenz/MeldungsRef[2]'
passing xmltype(msg_body)
returning content
) as second
from your_table;
Вы могли бы поискать второй, не являющийся нулевым, но проще использовать тот же XPath с xmlexists()
, чтобы проверить, существует ли второй дочерний узел:
select id
from your_table
where xmlexists(
'declare default element namespace "http://www.finnova.ch/ZV/EHF/021"; (: :)
/Body/Auftrag/Zahlungsliste/Zahlung/Referenz/MeldungsRef[2]'
passing xmltype(msg_body)
);
db<> возится с одной хорошей (один узел) и одной плохой (несколько узлов) строкой.
я получаю следующую ошибку: ORA-32512: введите ‘внешнюю переменную xquery’
Поскольку ваш базовый столбец представляет собой большой двоичный объект, вам нужно указать ему, какой это набор символов, например:
passing xmltype(msg_body, nls_charset_id('UTF8'))
Комментарии:
1. Большое спасибо, что помогли мне! К сожалению, я получаю следующую ошибку: ORA-32512: тип ‘внешняя переменная xquery’ неизвестен, что я делаю не так?
2. @mablaser — смотрите обновление; ему необходимо знать набор символов для содержимого большого двоичного объекта.