Eu corro para este mesmo problema (tanto em 11.2.0.3.0 quanto em 12.1.0.2.0). Parece que você não pode usar uma variável PL/SQL no lugar de XQuery_string em xmltable quando a string de consulta faz referência a um namespace. Observe que você pode usar uma variável PL/SQL se não fizer referência a um namespace (veja o exemplo nº 3 abaixo).
A exceção levantada descrição :
Se o fato de usar uma variável em vez de uma string literal parece ser preterido pelo Oracle. O documento de suporte da Oracle Doc ID 1490150.1 (disponível apenas para clientes pagantes) sugere que há um patch (o caso não é exatamente o mesmo que o nosso, mas muito semelhante), mas o documento também afirma que:
- usar uma variável em vez de um literal de string não é um comportamento padrão SQL/XML
- construir XPath/XQuery durante o tempo de execução tem uma severa penalidade de desempenho
E, portanto, a Oracle recomenda usar apenas literais de string.
Minha confusão inicial foi causada pelo seguinte conflito na própria documentação da Oracle (11.2):
Função XMLTABLE SQL/XML no banco de dados XML Oracle em Guia do desenvolvedor de banco de dados XML :
XMLTABLE em Referência de linguagem SQL de banco de dados :
Observe a falta de "como uma string literal" da segunda citação. E é claro que primeiro li apenas Referência da linguagem SQL do banco de dados ...
A documentação do XMLTABLE foi corrigida na versão 12.1 :
Então a resposta é que não use uma variável como XQuery_string até compila e em alguns casos parece funcionar.
Abaixo, você encontrará exemplos mínimos para reproduzir o problema:
Exemplo nº 1
Isso funciona e imprime 'This is A.' como esperado.
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;
/
Exemplo nº 2
Isso falha com:
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;
/
Exemplo nº 3
Isso funciona e imprime 'This is A.' como esperado.
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;
/