sql >> Database teknologi >  >> RDS >> Oracle

Brug af variabel til at definere stien i XMLTable i Oracle

Jeg løber til det samme problem (både i 11.2.0.3.0 og 12.1.0.2.0). Det ser ud til, at du ikke kan bruge en PL/SQL-variabel i stedet for XQuery_stringxmltable når forespørgselsstrengen refererer til et navneområde. Bemærk, at du kan bruge en PL/SQL-variabel, hvis du ikke refererer til et navneområde (se eksempel #3 nedenfor).

Den rejste undtagelse beskrivelse :

Hvis fakta, der bruger en variabel i stedet for en streng, ser ud til at være forældet af Oracle. Oracle supportdokument Doc ID 1490150.1 (kun tilgængelig for betalende kunder) antyder, at der er en patch (sagen er ikke nøjagtig den samme som vores sag, men meget ens), men dokumentet siger også, at:

  • brug af en variabel i stedet for en streng-literal er ikke SQL/XML-standardadfærd
  • at konstruere XPath/XQuery under kørsel har en alvorlig ydeevnestraf

Og derfor anbefaler Oracle kun at bruge strenge bogstaver.

Min første forvirring var forårsaget af følgende konflikt i Oracles egen dokumentation (11.2):

XMLTABLE SQL/XML-funktion i Oracle XML DB i XML DB-udviklervejledning :

XMLTABLE i Database SQL Language Reference :

Bemærk den manglende "som en streng bogstavelig" fra det andet citat. Og selvfølgelig læste jeg først kun Database SQL Language Reference ...

XMLTABLE-dokumentationen er blevet rettet i 12.1-version :

Så svaret er, at brug ikke en variabel som XQuery_string selv det kompilerer og ser i nogle tilfælde ud til at virke.

Nedenfor finder du minimale eksempler til at genskabe problemet:

Eksempel #1

Dette virker og udskriver 'This is A.' som forventet.

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

Eksempel #2

Dette mislykkes med:

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

Eksempel #3

Dette virker og udskriver 'This is A.' som forventet.

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. Hvordan last_insert_rowid() virker i SQLite

  2. pyodbc:Hvordan prøver man igen at gendanne fra forbigående fejl?

  3. Kommandoer ude af synkronisering; du kan ikke køre denne kommando nu

  4. Mysql-tidsstempel Data afkortet for kolonne