Docieram do tego samego problemu (zarówno w wersji 11.2.0.3.0, jak i 12.1.0.2.0). Wygląda na to, że nie możesz użyć zmiennej PL/SQL zamiast XQuery_string w xmltable gdy ciąg zapytania odwołuje się do przestrzeni nazw. Zauważ, że możesz użyć zmiennej PL/SQL, jeśli nie odwołujesz się do przestrzeni nazw (patrz przykład #3 poniżej).
Zgłoszony wyjątek opis :
Jeśli fakt używania zmiennej zamiast literału znakowego wydaje się być przestarzały przez Oracle. Dokument pomocy technicznej Oracle Doc ID 1490150.1 (dostępny tylko dla klientów płacących) sugeruje, że istnieje poprawka (przypadek nie jest dokładnie taki sam jak w naszym przypadku, ale bardzo podobny), ale dokument stwierdza również, że:
- używanie zmiennej zamiast literału ciągu nie jest standardowym zachowaniem SQL/XML
- konstruowanie XPath/XQuery w czasie wykonywania ma poważny spadek wydajności
Dlatego Oracle zaleca używanie tylko literałów łańcuchowych.
Moje początkowe zamieszanie było spowodowane następującym konfliktem we własnej dokumentacji Oracle (11.2):
Funkcja XMLTABLE SQL/XML w bazie danych Oracle XML w Podręczniku programisty XML DB :
XMLTABLE w Informacje o języku bazy danych SQL :
Zwróć uwagę na brak „jako literał ciągu” z drugiego cytatu. I oczywiście najpierw przeczytałem tylko Informacje o języku SQL w bazie danych ...
Dokumentacja XMLTABLE została poprawiona w wersja 12.1 :
Odpowiedź brzmi:nie używaj zmiennej jako XQuery_string nawet się kompiluje i w niektórych przypadkach wydaje się działać.
Poniżej znajdziesz minimalne przykłady odtworzenia problemu:
Przykład #1
To działa i drukuje „To jest A”. zgodnie z oczekiwaniami.
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;
/
Przykład #2
To się nie udaje z:
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;
/
Przykład #3
To działa i drukuje „To jest A”. zgodnie z oczekiwaniami.
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;
/