当 XPath 不存在时,Oracle XMLTABLE 左外连接不会 return 结果
Oracle XMLTABLE left outer join doesn't return results when XPath doesn't exist
table tbl 有一个类型为 XMLTYPE 的列 xml_data。
考虑以下 XML:
<root>
<element>
<id>1</id>
<data>abc</data>
</element>
<element>
<id>2</id>
<data>def</data>
</element>
</root>
我需要一个 select 语句,它将 return tbl 中每一行的 1 行,有 3 列:id1、id2 和 id3。
id1将从"id"为1的"element"节点中获取"data"标签的值,id2将从"id"为2的节点中获取值,依此类推
如果某个 id 没有元素(如上面 XML 中的 id3),NULL 将在该列中 returned。
所以对于上面的XML我想得到
id1
id2
id3
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 with ON 1=1)。
我注意到如果 XML 查询有效但 xmltable 中的“路径”不存在,它 确实 工作并且 NULL 被 returned(即使没有 (+) ),但是如果 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;
Returns:
id1
id2
id3
abc
def
-
不需要多次调用XMLTable,可以将元素选择移到列路径子句中,这样的子句有3个:
select x.id1, x.id2, x.id3
from tbl t
cross join
xmltable ('/root'
passing t.xml_data
columns id1 varchar2 (100) path 'element[id=1]/data',
id2 varchar2 (100) path 'element[id=2]/data',
id3 varchar2 (100) path 'element[id=3]/data'
) x;
ID1 ID2 ID3
----- ----- -----
abc def
希望对您有所帮助
WITH TEMP AS(
SELECT ID,DATA_VALUE
FROM XMLTABLE('./root/element' PASSING XMLTYPE('<root>
<element>
<id>1</id>
<data>abc</data>
</element>
<element>
<id>2</id>
<data>def</data>
</element>
</root>')
COLUMNS ID NUMBER PATH './id',
DATA_VALUE VARCHAR2(240) PATH './data'))
SELECT (SELECT DATA_VALUE FROM TEMP WHERE ID = 1) ID1,
(SELECT DATA_VALUE FROM TEMP WHERE ID = 2) ID2,
(SELECT DATA_VALUE FROM TEMP WHERE ID = 3) ID3
FROM DUAL;
table tbl 有一个类型为 XMLTYPE 的列 xml_data。 考虑以下 XML:
<root>
<element>
<id>1</id>
<data>abc</data>
</element>
<element>
<id>2</id>
<data>def</data>
</element>
</root>
我需要一个 select 语句,它将 return tbl 中每一行的 1 行,有 3 列:id1、id2 和 id3。
id1将从"id"为1的"element"节点中获取"data"标签的值,id2将从"id"为2的节点中获取值,依此类推
如果某个 id 没有元素(如上面 XML 中的 id3),NULL 将在该列中 returned。
所以对于上面的XML我想得到
id1 | id2 | id3 |
---|---|---|
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 with ON 1=1)。
我注意到如果 XML 查询有效但 xmltable 中的“路径”不存在,它 确实 工作并且 NULL 被 returned(即使没有 (+) ),但是如果 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;
Returns:
id1 | id2 | id3 |
---|---|---|
abc | def | - |
不需要多次调用XMLTable,可以将元素选择移到列路径子句中,这样的子句有3个:
select x.id1, x.id2, x.id3
from tbl t
cross join
xmltable ('/root'
passing t.xml_data
columns id1 varchar2 (100) path 'element[id=1]/data',
id2 varchar2 (100) path 'element[id=2]/data',
id3 varchar2 (100) path 'element[id=3]/data'
) x;
ID1 ID2 ID3
----- ----- -----
abc def
希望对您有所帮助
WITH TEMP AS(
SELECT ID,DATA_VALUE
FROM XMLTABLE('./root/element' PASSING XMLTYPE('<root>
<element>
<id>1</id>
<data>abc</data>
</element>
<element>
<id>2</id>
<data>def</data>
</element>
</root>')
COLUMNS ID NUMBER PATH './id',
DATA_VALUE VARCHAR2(240) PATH './data'))
SELECT (SELECT DATA_VALUE FROM TEMP WHERE ID = 1) ID1,
(SELECT DATA_VALUE FROM TEMP WHERE ID = 2) ID2,
(SELECT DATA_VALUE FROM TEMP WHERE ID = 3) ID3
FROM DUAL;