XML парсинг в Oracle
Выполняю запрос:
with demo as(
select XMLType('<items>
<item id="1745212" template="Бокс распределительный">
<p60226>DKC</p60226>
<p60227>R5PKEB2V81713B4P</p60227>
<p69317>Бокс распределительный</p69317>
</item>
<item id="1745213" template="Бокс распределительный">
<p60226>DKC</p60226>
<p60227>R5PKEB2V817144P</p60227>
<p69317>Бокс распределительный малый</p69317>
</item>
</items>'
) xml from dual)
select
extractvalue(value(dt1),'/item/@id') id,
dt2.column_value.getrootelement() property_name,
extractValue(value(dt2),'/*') value
from
demo s,
table(XMLSequence(s.xml.extract('/items/item'))) dt1,
table(XMLSequence(s.xml.extract('/items/item/*'))) dt2
Ожидаю на выходе 6 строк вида: item_id, property_name (имя тэга), value Получаю 12. Т.е. для каждого item_id все 6 value, хотелось бы только 3, к нему относящиеся. И вроде причина понятна, но вот как пофиксить дублирование ? Спасибо !
Ответы (1 шт):
Автор решения: 0xdb
→ Ссылка
Таблицы dt1 и dt2 выбирают из одного и того же документа s.xml, и как следствие, декартово произведение этих двух таблиц.
Функции: XMLSequence, extractvalue, getrootelement в 11.2.0.1 объявлены устаревшими, они не рекомендуются больше к применению.
Попробуйте с XMLTable (на db<>fiddle):
with doc (xml) as (
select xmlType (
'<items>
<item id="1745212" template="Бокс распределительный">
<p60226>DKC</p60226>
<p60227>R5PKEB2V81713B4P</p60227>
<p69317>Бокс распределительный</p69317>
</item>
<item id="1745213" template="Бокс распределительный">
<p60226>DKC</p60226>
<p60227>R5PKEB2V817144P</p60227>
<p69317>Бокс распределительный малый</p69317>
</item>
</items>') from dual)
select id, name, value
from doc, xmlTable ('/items/item/*' passing doc.xml columns
id number path './../@id',
name varchar2 (8) path 'name()',
value varchar2 (64) path 'text()')
Результат как и ожидался:
ID NAME VALUE
---------- -------- --------------------------------
1745212 p60226 DKC
1745212 p60227 R5PKEB2V81713B4P
1745212 p69317 Бокс распределительный
1745213 p60226 DKC
1745213 p60227 R5PKEB2V817144P
1745213 p69317 Бокс распределительный малый
6 rows selected.