sql >> Database >  >> RDS >> Oracle

Variabele gebruiken om pad te definiëren in XMLTable in Oracle

Ik loop tegen hetzelfde probleem aan (zowel in 11.2.0.3.0 als 12.1.0.2.0). Het lijkt erop dat u geen PL/SQL-variabele kunt gebruiken in plaats van XQuery_string op xmltable wanneer de querytekenreeks verwijst naar een naamruimte. Merk op dat u een PL/SQL-variabele kunt gebruiken als u niet naar een naamruimte verwijst (zie voorbeeld #3 hieronder).

De verhoogde uitzondering beschrijving :

Als het gebruik van een variabele in plaats van een letterlijke tekenreeks door Oracle lijkt te worden afgeraden. Oracle-ondersteuningsdocument Doc ID 1490150.1 (alleen beschikbaar voor betalende klanten) suggereert dat er een patch is (de case is niet precies hetzelfde als onze case, maar lijkt erg op) maar het document stelt ook dat:

  • het gebruik van een variabele in plaats van een letterlijke tekenreeks is geen standaard SQL/XML-gedrag
  • het bouwen van XPath/XQuery tijdens runtime heeft een ernstige prestatiestraf

En daarom raadt Oracle aan om alleen tekenreeksen te gebruiken.

Mijn aanvankelijke verwarring werd veroorzaakt door het volgende conflict in Oracle's eigen documentatie (11.2):

XMLTABLE SQL/XML-functie in Oracle XML DB in XML DB Developer's Guide :

XMLTABLE in Database SQL-taalreferentie :

Let op de ontbrekende "als een letterlijke tekenreeks" uit het tweede citaat. En natuurlijk lees ik eerst alleen Database SQL-taalreferentie ...

De XMLTABLE-documentatie is opgelost in 12.1 versie :

Dus het antwoord is dat je geen variabele gebruikt als XQuery_string zelfs het compileert en in sommige gevallen lijkt het te werken.

Hieronder vindt u minimale voorbeelden om het probleem te reproduceren:

Voorbeeld #1

Dit werkt en drukt 'This is A.' zoals verwacht.

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

Voorbeeld #2

Dit mislukt met:

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

Voorbeeld #3

Dit werkt en drukt 'This is A.' zoals verwacht.

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. Hoe kan ik de SID van een Oracle XE-instantie wijzigen?

  2. MySQL - Lijst trekken afhankelijk van datum en categorie

  3. Is het een slechte gewoonte om de instructie EXIT WHEN te gebruiken bij het doorlopen van CURSOR's in Oracle?

  4. Tabel splitsen in kolommen op verschillende niveaus