2015-04-21 21 views
7

Używam Oracle 11.2.0.4.0 i miałem kilka razy problemy, gdy był zaangażowany XMLTABLE. Mój ostatni problem można przedstawić następującym przykładzie (które zaprojektowane, aby być tak proste, jak to możliwe):Dziwny błąd z XMLTABLE na Oracle 11g

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; 

produkuje następujący błąd:

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 

natomiast następujące kwerendy działa zgodnie z oczekiwaniami (the z klauzuli jest bez zmian):

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 

Dalsza kwerenda działa, jeśli użycie XMLTABLE unika:

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 

Mam więc obejście problemu i będę unikać używania XMLTABLE, o ile nie rozumiem opisanego powyżej zachowania. Czy XMLTABLE jest uważany za błędny, czy też czegoś brakuje?

+1

Powtarzalne w 11.2.0.3; na 10.2.0.5 to core-dumps (choć z dodatkiem NO_XML_QUERY_REWRITE wskazówka, aby uniknąć błędu 5963973 również to pokazuje). Wygląda to jak błąd i prawdopodobnie powinieneś zgłosić żądanie usługi, aby to zgłosić. –

+1

Myślę, że jest błąd. Kiedy dodaję 'NVL' do wyrażenia -' xmltype (NVL (d.x, '')) 'to zapytanie zostanie wykonane, ale nie zwróci żadnego wiersza. 'z danymi jako ( wybierz" B21 x z podwójnym ) extractedxml jako ( select B Z danych D xmltable ('/ A/B' przechodzącą XMLType (NVL (DX ' ')) KOLUMNY b VARCHAR2 (20) Path) ) select b z extractedxml UNION select b z extractedxml' –

+1

@Asieh'.': podczas edycji, należy pamiętać, że przęseł kodu inline ('jak this') [nie powinny być używane do podświetlania] (http://meta.stackoverflow.com/q/254990), tylko dla kodu w zdaniach. Spróbuj również poprawić post tak bardzo, jak to możliwe podczas edycji, aby zaoszczędzić czas recenzentów. Dzięki! –

Odpowiedz

2

Zgodnie z moim doświadczeniem dobrze jest dodać kolejną kolumnę dla porządku do xmltable.

Ta instrukcja SQL działa bez zarzutu:

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; 

Kolejny krytyczny problem spowodowany przez omiting kolumnę dla ordinality:

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 (!) 

Ale

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 
+0

To działa (przynajmniej w moim przypadku użycia). Dzięki! – Branko