Saya mengalami masalah yang sama (baik di 11.2.0.3.0 dan 12.1.0.2.0). Sepertinya Anda tidak dapat menggunakan variabel PL/SQL sebagai pengganti XQuery_string di xmltable ketika string kueri mereferensikan namespace. Perhatikan bahwa Anda dapat menggunakan variabel PL/SQL jika Anda tidak mereferensikan namespace (lihat contoh #3 di bawah).
Pengecualian yang diajukan deskripsi :
Jika fakta menggunakan variabel alih-alih string literal tampaknya sudah ditinggalkan oleh Oracle. Dokumen dukungan Oracle, Doc ID 1490150.1 (hanya tersedia untuk pelanggan yang membayar) menunjukkan bahwa ada tambalan (kasusnya tidak persis sama dengan kasing kami tetapi sangat mirip) tetapi dokumen tersebut juga menyatakan bahwa:
- menggunakan variabel sebagai ganti literal string bukanlah perilaku standar SQL/XML
- membangun XPath/XQuery selama runtime memiliki penalti kinerja yang parah
Dan oleh karena itu Oracle merekomendasikan penggunaan string literal saja.
Kebingungan awal saya disebabkan oleh konflik berikut dalam dokumentasi Oracle sendiri (11.2):
Fungsi SQL/XML XMLTABLE di Oracle XML DB di Panduan Pengembang XML DB :
XMLTABLE di Referensi Bahasa SQL Database :
Perhatikan "sebagai string literal" . yang hilang dari kutipan kedua. Dan tentu saja saya pertama kali hanya membaca Referensi Bahasa SQL Database ...
Dokumentasi XMLTABLE telah diperbaiki di versi 12.1 :
Jadi jawabannya adalah jangan gunakan variabel sebagai XQuery_string bahkan dikompilasi dan dalam beberapa kasus tampaknya berhasil.
Di bawah ini Anda akan menemukan contoh minimal untuk mereproduksi masalah:
Contoh #1
Ini berfungsi dan mencetak 'Ini adalah A.' seperti yang diharapkan.
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;
/
Contoh #2
Ini gagal dengan:
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;
/
Contoh #3
Ini berfungsi dan mencetak 'Ini adalah A.' seperti yang diharapkan.
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;
/