В таблице tbl есть столбец xml_data типа XMLTYPE. Рассмотрим следующий XML:
<root>
<element>
<id>1</id>
<data>abc</data>
</element>
<element>
<id>2</id>
<data>def</data>
</element>
</root>
Мне нужен оператор выбора, который будет возвращать 1 строку для каждой строки в таблице с 3 столбцами: id1, id2 и id3.
id1 получит значение тега «данные» из узла «элемент», где «id» равен 1. id2 получит значение из узла, где «id» равен 2, и т. д.
Если для определенного идентификатора нет элемента (например, id3 в приведенном выше XML), в этом столбце будет возвращено значение NULL.
Итак, для приведенного выше XML я хочу получить
id1 id2 id3
--------------------
1 abc def -
Я старался:
select id1.val, id2.val, id3.val
from tbl t,
xmltable ('/root/element[id=1]'
passing t.xml_data
columns val varchar2 (100) path 'data') id1,
xmltable ('/root/element[id=2]'
passing t.xml_data
columns val varchar2 (100) path 'data') id2,
xmltable ('/root/element[id=3]'
passing t.xml_data
columns val varchar2 (100) path 'data') id3;
Но я получаю 0 строк, потому что нет '/root/element[id=3]'.
Я попытался добавить (+):
xmltable ('/root/element[id=3]'
passing t.xml_data
columns val varchar2 (100) path 'data') (+) id3;
Это не помогло (ни LEFT OUTER JOIN с ON 1=1).
Я заметил, что если XMLQuery действителен, но «путь» внутри xmltable не существует, он РАБОТАЕТ и возвращается NULL (даже без (+) ), но если сам XQuery не не существует, так как в [id=3] это не работает.
select id1.val, id2.val, id3.val
from tbl t,
xmltable ('/root/element[id=1]'
passing t.xml_data
columns val varchar2 (100) path 'data') id1,
xmltable ('/root/element[id=2]'
passing t.xml_data
columns val varchar2 (100) path 'data') id2,
xmltable ('/root/element[id=2]'
passing t.xml_data
columns val varchar2 (100) path 'doesnt-exist') id3;
Возвращает:
id1 id2 id3
--------------------
1 abc def -