Inserting a child node in an XMLTYPE column

坚强是说给别人听的谎言 提交于 2019-12-23 07:39:11

问题


I have a simple query:

WITH xtbl AS (
  SELECT XMLTYPE ('<a><b>1</b></a>') AS xcol 
    FROM DUAL
)
SELECT XMLQUERY ('copy $tmp := . 
                    modify 
                       insert node <c>2</c>
                         into $tmp/a/b
                       return $tmp'
                 PASSING xcol 
               RETURNING CONTENT) AS newxcol
  FROM xtbl;

What I'm trying to do is to insert a node <c> after <b> inside the node <a> but Oracle 12c is throwing this error:

ORA-19114: XPST0003 - error during parsing the XQuery expression: 
           LPX-00801: XQuery syntax error at 'EOF'
           5   -
           -  ^

I want the output as:

NEWXCOL
-------------
<a>
    <b>1</b>
    <c>2</c/>
</a>

I have tried looking in Oracle Docs for a replacement of appendChildXML and follow that example but only got the error.

I know it is very basic and I'm missing something obvious. Please help.


回答1:


Following code should be working for 11 and 12 (deprecated):

SELECT insertXMLafter(XMLType('<a><b>1</b><c>3</c></a>'),
                 '/a/b', XmlType('<c>2</c>'))
  FROM dual;

Same code using new XMLQuery syntax:

SELECT XMLQuery('copy $tmp := . modify insert node 
                 <c>2</c>
                 after $tmp/a/b 
                 return $tmp'
                PASSING XmlType('<a><b>1</b><c>3</c></a>') RETURNING CONTENT)
  FROM dual;

More details regarding XMLQuery and also the old deprecated functions can be found here: http://docs.oracle.com/database/121/ADXDB/app_depr_upd.htm#ADXDB6160




回答2:


One ugly but possible way to use only one SQL query that works correctly on older and current database versions would be to use the CASE method in SQL:

WITH tbl AS
 (SELECT SUBSTR(MAX(version),1,2) as ver, XMLType('<a><b>1</b><c>3</c></a>') as xcol
    FROM v$instance)
SELECT 
   CASE WHEN ver < '12' THEN
      insertXMLafter(xcol,
                 '/a/b', XmlType('<c>2</c>'))
   ELSE
      XMLQuery('copy $tmp := . modify insert node 
                 <c>2</c>
                 after $tmp/a/b 
                 return $tmp'
                PASSING xcol RETURNING CONTENT) 
   END
FROM tbl;

Of course that won't help you if the insertXMLafter method gets removed in future releases of the database. That would produce an invalid SQL. But for now you would be good and use the right method on the right versions.



来源:https://stackoverflow.com/questions/24824336/inserting-a-child-node-in-an-xmltype-column

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!