Sql 修改Oracle 12c的XML节点值-UpdateXML等效值

Sql 修改Oracle 12c的XML节点值-UpdateXML等效值,sql,xml,oracle,xquery,oracle12c,Sql,Xml,Oracle,Xquery,Oracle12c,我有一些示例代码,如下所示: WITH xtbl AS (SELECT 1 AS xtbl_id, xmltype ('<node_root> <node_1>12</node_1> <node_2>233</node_2> <node_

我有一些示例代码,如下所示:

WITH xtbl AS
         (SELECT 1 AS xtbl_id,
                 xmltype ('<node_root>
                        <node_1>12</node_1>
                        <node_2>233</node_2>
                        <node_3>223</node_3>
                        <node_4>234</node_4>
                   </node_root>') AS x
            FROM Dual
          UNION ALL
          SELECT 2, xmltype ('<node_root>
                        <node_1></node_1>
                        <node_2>233</node_2>
                        <node_3>223</node_3>
                        <node_4>234</node_4>
                   </node_root>')
            FROM Dual)
SELECT xtbl_id,
       x,
       Updatexml (x,
                  '/node_root/node_2',
                  NULL,
                  '/node_root/node_3',
                  NULL,
                  '/node_root/node_4',
                  NULL)
           AS xcol
  FROM xtbl
 WHERE (SELECT node_1
          FROM Xmltable ('node_root'
                         PASSING x
                         COLUMNS node_1 INTEGER PATH 'node_1'))
           IS NOT NULL;
我的要求是,只要x列中的/node_root/node_1不为null,就将/node_root/node_2、/node_root/node_3和/node_root/node_4的值替换为null。我在SELECT查询中使用的Updatexml函数也执行相同的操作

这里的问题是Updatexml在Oracle 12c中不起作用。这就是为什么我在子查询中使用了Xmltable,它可以完美地过滤数据,但我不能用null替换节点值

我尝试查看XQuery,但不明白它在替换节点值方面有何帮助

请提供一个描述性示例。

Oracle文档。所以这是第一件要尝试的事情

首先,使用旧的函数方法是可能的。可以使用下面的XQuery代替对XmlUpdate的调用:

此外,仅当条件不匹配时,才可以返回修改后的XML值:

WITH xtbl AS
     (SELECT 1 AS xtbl_id,
             xmltype ('<node_root>
                    <node_1>12</node_1>
                    <node_2>233</node_2>
                    <node_3>223</node_3>
                    <node_4>234</node_4>
               </node_root>') AS x
        FROM Dual
      UNION ALL
      SELECT 2, xmltype ('<node_root>
                    <node_1></node_1>
                    <node_2>233</node_2>
                    <node_3>223</node_3>
                    <node_4>234</node_4>
               </node_root>')
        FROM Dual)
SELECT xtbl_id,
   x,
    XMLQuery(
      '   
        for $test in $p/*
        return 
          if( empty($p/node_root/node_1/text()) )             
            then $p
            else (
             copy $p2 := $p
              modify(
                replace value of node $p2/node_root/node_2 with "",
                replace value of node $p2/node_root/node_3 with "",
                replace value of node $p2/node_root/node_4 with ""
              )
              return $p2
           )   
      '
      passing x as "p" returning content
    ) as xcol_4
FROM xtbl

因此,有许多变体可以对XML值执行操作,但这需要对相对简单的XmlUpdate函数有更深入的了解…

第一个代码示例适用于11gR2和12c。第二个和第三个示例仅适用于12c。谢谢这很奇怪,因为我针对Oracle的11.2.0.3版本测试了所有变体。你能发布你的Oracle的准确版本吗?例如,从v$版本中选择*吗?有两个版本-11.2.0.1.0和12.1.0.1.0,都是64位。我喜欢从11.2.0.3开始工作。对不起,找不到官方证据。没问题。您的第一个示例在11.2.0.1中运行,这对我来说已经足够了。谢谢
    XMLQuery(
      '              
        copy $p2 := $p
        modify(
          replace value of node $p2/node_root/node_2 with "",
          replace value of node $p2/node_root/node_3 with "",
          replace value of node $p2/node_root/node_4 with ""
        )
        return $p2
      '
      passing x as "p" returning content
    ) as xcol_3
WITH xtbl AS
     (SELECT 1 AS xtbl_id,
             xmltype ('<node_root>
                    <node_1>12</node_1>
                    <node_2>233</node_2>
                    <node_3>223</node_3>
                    <node_4>234</node_4>
               </node_root>') AS x
        FROM Dual
      UNION ALL
      SELECT 2, xmltype ('<node_root>
                    <node_1></node_1>
                    <node_2>233</node_2>
                    <node_3>223</node_3>
                    <node_4>234</node_4>
               </node_root>')
        FROM Dual)
SELECT xtbl_id,
   x,
    XMLQuery(
      '   
        for $test in $p/*
        return 
          if( empty($p/node_root/node_1/text()) )             
            then $p
            else (
             copy $p2 := $p
              modify(
                replace value of node $p2/node_root/node_2 with "",
                replace value of node $p2/node_root/node_3 with "",
                replace value of node $p2/node_root/node_4 with ""
              )
              return $p2
           )   
      '
      passing x as "p" returning content
    ) as xcol_4
FROM xtbl