Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Menggunakan variabel untuk menentukan jalur di XMLTable di Oracle

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;
/


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana menangani penyisipan bersamaan ke dalam DB yang menyebabkan pelanggaran aturan untuk catatan dalam database?

  2. Oracle Sql :Prosedur yang dapat membuat tabel sementara di dalamnya

  3. cara menggunakan batasan cek di oracle

  4. Perbandingan tanggal Oracle di mana klausa

  5. Oracle SQL:memilih dari all_tab_columns tidak menemukan kolom yang ada