Corro a questo stesso problema (sia in 11.2.0.3.0 che 12.1.0.2.0). Sembra che tu non possa usare una variabile PL/SQL al posto di XQuery_string su xmltable quando la stringa di query fa riferimento a uno spazio dei nomi. Nota che puoi utilizzare una variabile PL/SQL se non fai riferimento a uno spazio dei nomi (vedi esempio n. 3 di seguito).
L'eccezione sollevata descrizione :
Se il fatto che utilizza una variabile invece di una stringa letterale sembra essere deprecato da Oracle. Il documento di supporto Oracle Doc ID 1490150.1 (disponibile solo per i clienti paganti) suggerisce che esiste una patch (il caso non è esattamente lo stesso del nostro caso ma è molto simile) ma il documento afferma anche che:
- l'uso di una variabile invece di una stringa letterale non è un comportamento standard SQL/XML
- La costruzione di XPath/XQuery durante il runtime comporta una grave penalizzazione delle prestazioni
E quindi Oracle consiglia di utilizzare solo stringhe letterali.
La mia confusione iniziale è stata causata dal seguente conflitto nella documentazione di Oracle (11.2):
Funzione XMLTABLE SQL/XML nel DB Oracle XML in Guida per sviluppatori XML DB :
XMLTABLE in Riferimento al linguaggio SQL del database :
Nota il "come stringa letterale" mancante dalla seconda citazione. E ovviamente prima leggo solo Database SQL Language Reference ...
La documentazione XMLTABLE è stata corretta in versione 12.1 :
Quindi la risposta è che non usa una variabile come XQuery_string anche si compila e in alcuni casi sembra funzionare.
Di seguito troverai esempi minimi per riprodurre il problema:
Esempio n. 1
Funziona e stampa 'This is A.' come previsto.
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;
/
Esempio n. 2
Questo non riesce con:
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;
/
Esempio n. 3
Funziona e stampa 'This is A.' come previsto.
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;
/