Oracle
 sql >> база данни >  >> RDS >> Oracle

Използване на променлива за дефиниране на път в XMLTable в Oracle

Сблъсквам се със същия проблем (и в 11.2.0.3.0, и в 12.1.0.2.0). Изглежда, че не можете да използвате PL/SQL променлива на мястото на XQuery_string в xmltable когато низът на заявката препраща към пространство от имена. Имайте предвид, че можете да използвате PL/SQL променлива, ако не препращате към пространство от имена (вижте пример #3 по-долу).

Повдигнатото изключение описание :

Ако фактът, че използването на променлива вместо низов литерал изглежда е отхвърлено от Oracle. Документът за поддръжка на Oracle Doc ID 1490150.1 (достъпен само за плащащи клиенти) предполага, че има корекция (случаят не е точно същият като нашия случай, но много подобен), но документът също така посочва, че:

  • използването на променлива вместо низов литерал не е стандартно поведение на SQL/XML
  • конструирането на XPath/XQuery по време на изпълнение има сериозно увреждане на производителността

И затова Oracle препоръчва използването само на низови литерали.

Първоначалното ми объркване беше причинено от следния конфликт в собствената документация на Oracle (11.2):

XMLTABLE SQL/XML функция в Oracle XML DB в Ръководство за разработчици на XML DB :

XMLTABLE в Справочник за SQL език на база данни :

Обърнете внимание на липсващия "като низов литерал" от втория цитат. И разбира се, първо прочетох само Database SQL Language Refererence ...

Документацията на XMLTABLE е коригирана във версия 12.1 :

Така че отговорът е, че не използвайте променлива като XQuery_string дори се компилира и в някои случаи изглежда работи.

По-долу ще намерите минимални примери за възпроизвеждане на проблема:

Пример №1

Това работи и отпечатва „Това е A.“ както се очаква.

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

Пример №2

Това се проваля с:

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

Пример №3

Това работи и отпечатва „Това е A.“ както се очаква.

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. Грешка при изключване на Oracle ORA-01033

  2. Изпълнете async съхранена процедура в sql developer

  3. Как работи contains() в PL-SQL?

  4. Как да използвате асоциативен масив на Oracle в SQL заявка

  5. Грешка в изхода на SQL Fiddle