Tôi chạy đến vấn đề này rất giống nhau (cả trong 11.2.0.3.0 và 12.1.0.2.0). Có vẻ như bạn không thể sử dụng biến PL / SQL thay cho XQuery_string tại xmltable khi chuỗi truy vấn tham chiếu đến một không gian tên. Lưu ý rằng bạn có thể sử dụng biến PL / SQL nếu bạn không tham chiếu không gian tên (xem ví dụ # 3 bên dưới).
Ngoại lệ nêu ra mô tả :
Nếu thực tế, việc sử dụng một biến thay vì một chuỗi ký tự dường như không được Oracle chấp nhận. Tài liệu hỗ trợ của Oracle Doc ID 1490150.1 (chỉ có sẵn cho khách hàng trả phí) cho thấy có một bản vá (trường hợp không hoàn toàn giống trường hợp của chúng tôi nhưng rất giống trường hợp của chúng tôi) nhưng tài liệu cũng nói rằng:
- sử dụng một biến thay vì một chuỗi ký tự không phải là hành vi chuẩn của SQL / XML
- xây dựng XPath / XQuery trong thời gian chạy có một hình phạt hiệu suất nghiêm trọng
Và do đó Oracle khuyến nghị chỉ sử dụng các ký tự chuỗi.
Sự nhầm lẫn ban đầu của tôi là do xung đột sau trong tài liệu của chính Oracle (11.2):
Hàm XMLTABLE SQL / XML trong Oracle XML DB trong Hướng dẫn của nhà phát triển XML DB :
XMLTABLE trong Tham chiếu ngôn ngữ SQL của cơ sở dữ liệu :
Lưu ý thiếu "dưới dạng một chuỗi ký tự" từ câu trích dẫn thứ hai. Và tất nhiên, lần đầu tiên tôi chỉ đọc Tham chiếu ngôn ngữ SQL cơ sở dữ liệu ...
Tài liệu XMLTABLE đã được sửa trong phiên bản 12.1 :
Vì vậy, câu trả lời là không sử dụng biến là XQuery_string thậm chí nó còn biên dịch và trong một số trường hợp dường như hoạt động.
Dưới đây, bạn sẽ tìm thấy các ví dụ tối thiểu để tái tạo vấn đề:
Ví dụ số 1
Điều này hoạt động và in ra 'Đây là A.' như mong đợi.
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;
/
Ví dụ số 2
Điều này không thành công với:
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;
/
Ví dụ số 3
Điều này hoạt động và in ra 'Đây là A.' như mong đợi.
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;
/