7

我正在使用Oracle 11.2.0.4.0并且在涉及时遇到了几次问题XMLTABLE。我的最新问题可以用下面的例子来演示(我设计得尽可能简单):

with data as
(
  select '<A><B>B21</B></A>' x from dual
),
extractedxml as (
  SELECT b
  FROM data d,
       xmltable('/A/B' PASSING xmltype(d.x) COLUMNS b varchar2(20) PATH '.')
)
select b from extractedxml union 
select b from extractedxml;

产生以下错误:

ORA-19032: Expected XML tag , got no content
ORA-06512: at "SYS.XMLTYPE", line 310
ORA-06512: at line 1
19032. 00000 -  "Expected XML tag %s got %s"
*Cause:    When converting XML to object, a wrong tag name was present
*Action:   Pass a valid canonical XML that can map to the given object type

虽然以下查询按预期工作(with 子句未更改):

with data as
(
  select '<A><B>B21</B></A>' x from dual
),
extractedxml as (
  SELECT b
  FROM data d,
       xmltable('/A/B' PASSING xmltype(d.x) COLUMNS b varchar2(20) PATH '.')
)
select b from extractedxml;

B
--------------------
B21

此外,如果XMLTABLE避免使用 ,则查询有效:

with data as
(
  select '<A><B>B21</B></A>' x from dual
),
extractedxml as (
  SELECT cast (extractvalue(column_value,'B') as varchar2(20)) b
  FROM data, table(xmlsequence(extract(xmltype(data.x),'/A/B')))
)
select b from extractedxml union 
select b from extractedxml;

B
--------------------
B21

所以我有一个解决方法,XMLTABLE只要我不理解上述行为,我就会避免使用。被XMLTABLE认为是越野车还是我错过了什么?

4

1 回答 1

2

根据我的经验,在 xmltable 中添加另一列用于序数是一个好主意。

此 SQL 语句工作正常:

with data as
(
  select '<A><B>B21</B></A>' x from dual
),
extractedxml as (
  SELECT b
  FROM data d,
       xmltable('/A/B' PASSING xmltype(d.x) COLUMNS i FOR ORDINALITY, b varchar2(20) PATH '.')
)
select b from extractedxml union 
select b from extractedxml;

省略序数列导致的另一个致命问题:

with data as
(
  select xmltype('<A><B>B21</B></A>') x from dual
),
extractedxml as (
  SELECT b
  FROM data d,
       xmltable('/A/B' PASSING d.x COLUMNS b varchar2(20) PATH '.')
)
select b from extractedxml union 
select b from extractedxml;

>> no result (!)

with data as
(
  select xmltype('<A><B>B21</B></A>') x from dual
),
extractedxml as (
  SELECT b
  FROM data d,
       xmltable('/A/B' PASSING d.x COLUMNS i FOR ORDINALITY, b varchar2(20) PATH '.')
)
select b from extractedxml union 
select b from extractedxml;

>> B21
于 2015-05-15T13:00:31.787 回答