Странная ошибка с XMLTABLE в Oracle 11g

Я использую 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 считать глючным или я что-то упускаю?


person Branko    schedule 21.04.2015    source источник
comment
Воспроизводится в 11.2.0.3; на 10.2.0.5 он создает дамп ядра (хотя с добавлением подсказки NO_XML_QUERY_REWRITE, чтобы избежать ошибки 5963973, он также показывает это поведение). Похоже на ошибку, и вам, вероятно, следует подать запрос на обслуживание, чтобы сообщить об этом.   -  person Alex Poole    schedule 21.04.2015
comment
Я думаю, что есть ошибка. Когда я добавляю NVL к выражению - xmltype(NVL(d.x,'<null/>')), тогда запрос выполняется, но не возвращает никакой строки. with data as ( select '<A><B>B21</B></A>' x from dual ), extractedxml as ( SELECT b FROM data d, xmltable('/A/B' PASSING xmltype(NVL(d.x,'<null/>')) COLUMNS b varchar2(20) PATH '.') ) select b from extractedxml UNION select b from extractedxml   -  person Janis Baiza    schedule 21.04.2015
comment
@Asieh: при редактировании обратите внимание, что встроенный код spans (like this) не должен использоваться для выделения, только для кода в предложениях. Кроме того, пожалуйста, постарайтесь максимально улучшить сообщение при редактировании, чтобы сэкономить время рецензентов. Спасибо!   -  person Qantas 94 Heavy    schedule 21.04.2015


Ответы (1)


По моему опыту, рекомендуется добавить еще один столбец для порядкового номера в 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
person Frank Ockenfuss    schedule 15.05.2015