Jag stöter på samma problem (både i 11.2.0.3.0 och 12.1.0.2.0). Det verkar som att du inte kan använda en PL/SQL-variabel i stället för XQuery_string på xmltabell när frågesträngen refererar till ett namnområde. Observera att du kan använda en PL/SQL-variabel om du inte refererar till ett namnområde (se exempel #3 nedan).
Det upphöjda undantaget beskrivning :
Om faktum att använda en variabel istället för en bokstavlig sträng verkar vara utfasad av Oracle. Oracle supportdokument Doc ID 1490150.1 (endast tillgängligt för betalande kunder) antyder att det finns en patch (fallet är inte exakt detsamma som vårt fall men väldigt likt) men dokumentet säger också att:
- att använda en variabel istället för en strängliteral är inte SQL/XML-standardbeteende
- att konstruera XPath/XQuery under körning har en allvarlig prestandastraff
Och därför rekommenderar Oracle att du endast använder bokstavssträngar.
Min första förvirring orsakades av följande konflikt i Oracles egen dokumentation (11.2):
XMLTABLE SQL/XML-funktion i Oracle XML DB i XML DB Developer's Guide :
XMLTABELL i Databas SQL Language Reference :
Notera att "som en sträng bokstavlig" saknas från det andra citatet. Och naturligtvis läste jag först bara Databas SQL Language Referens ...
XMLTABLE-dokumentationen har åtgärdats i 12.1-version :
Så svaret är att använd inte en variabel som XQuery_string även den kompilerar och verkar i vissa fall fungera.
Nedan hittar du minimala exempel för att återskapa problemet:
Exempel #1
Detta fungerar och skriver ut "This is A." som förväntat.
declare
v_xml constant xmltype := xmltype('
<ns:a
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns="http://stackoverflow.com/users/272735/a">
<foo><bar>This is A.</bar></foo>
</ns:a>
');
v_content varchar2(100);
begin
select bar into v_content
from xmltable(
xmlnamespaces('http://stackoverflow.com/users/272735/a' as "ns")
,'/ns:a/foo' passing v_xml
columns
bar varchar2(4000) path 'bar'
);
dbms_output.put_line(v_content);
end;
/
Exempel 2
Detta misslyckas med:
ORA-19112: error raised during evaluation:
XVM-01081: [XPST0081] Invalid prefix
1 /ns:a/foo
- ^
declare
v_xml constant xmltype := xmltype('
<ns:a
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns="http://stackoverflow.com/users/272735/a">
<foo><bar>This is A.</bar></foo>
</ns:a>
');
v_xquery_string constant varchar2(100) := '/ns:a/foo';
v_content varchar2(100);
begin
select bar into v_content
from xmltable(
xmlnamespaces('http://stackoverflow.com/users/272735/a' as "ns")
,v_xquery_string passing v_xml
columns
bar varchar2(4000) path 'bar'
);
dbms_output.put_line(v_content);
end;
/
Exempel 3
Detta fungerar och skriver ut "This is A." som förväntat.
declare
v_xml constant xmltype := xmltype('<a><foo><bar>This is A.</bar></foo></a>');
v_xquery_string constant varchar2(100) := '/a/foo';
v_content varchar2(100);
begin
select bar into v_content
from xmltable(
v_xquery_string passing v_xml
columns
bar varchar2(4000) path 'bar'
);
dbms_output.put_line(v_content);
end;
/