Сблъсквам се със същия проблем (и в 11.2.0.3.0, и в 12.1.0.2.0). Изглежда, че не можете да използвате PL/SQL променлива на мястото на XQuery_string в xmltable когато низът на заявката препраща към пространство от имена. Имайте предвид, че можете да използвате PL/SQL променлива, ако не препращате към пространство от имена (вижте пример #3 по-долу).
Повдигнатото изключение описание :
Ако фактът, че използването на променлива вместо низов литерал изглежда е отхвърлено от Oracle. Документът за поддръжка на Oracle Doc ID 1490150.1 (достъпен само за плащащи клиенти) предполага, че има корекция (случаят не е точно същият като нашия случай, но много подобен), но документът също така посочва, че:
- използването на променлива вместо низов литерал не е стандартно поведение на SQL/XML
- конструирането на XPath/XQuery по време на изпълнение има сериозно увреждане на производителността
И затова Oracle препоръчва използването само на низови литерали.
Първоначалното ми объркване беше причинено от следния конфликт в собствената документация на Oracle (11.2):
XMLTABLE SQL/XML функция в Oracle XML DB в Ръководство за разработчици на XML DB :
XMLTABLE в Справочник за SQL език на база данни :
Обърнете внимание на липсващия "като низов литерал" от втория цитат. И разбира се, първо прочетох само Database SQL Language Refererence ...
Документацията на XMLTABLE е коригирана във версия 12.1 :
Така че отговорът е, че не използвайте променлива като XQuery_string дори се компилира и в някои случаи изглежда работи.
По-долу ще намерите минимални примери за възпроизвеждане на проблема:
Пример №1
Това работи и отпечатва „Това е A.“ както се очаква.
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;
/
Пример №2
Това се проваля с:
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;
/
Пример №3
Това работи и отпечатва „Това е A.“ както се очаква.
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;
/