结合"变换" Oracle XMLQuery中的FLWOR表达式和FLWOR表达式

时间:2016-11-02 09:42:26

标签: sql oracle11g xquery flwor

在下面的代码中,我试图插入"名称"从oldXml2到oldXml的元素并更新" test" oldXml中的属性值为" newTest",得到的组合输出为newXml。 代码成功更改了属性值,但是当我添加:

let $newName := $b/users/user/name

子句从oldXml2获取name元素它停止工作。 有没有人有解决这个问题的方法?

我使用的是使用xquery 1.0的Oracle 11g。

WITH myXml AS (select 1 id, xmltype(
 '<users>
  <user test="oldvalue">
   <userid>id1</userid>
   <name>dave</name>
  </user>
</users>
'
 ) oldXml
 from dual),
myXml2 AS (select 1 id,xmltype(
 '<users>
  <user>
   <userid>id2</userid>
   <name>steve</name>
  </user>
</users>
'
 ) oldXml2
 from dual)
  SELECT oldXml,oldXml2,
XMLQuery(' copy $c := $a
       (: let $newName := $b/users/user/name :)  (: If you add this clause it doesnt work:)
         modify ( rename node $c/users/user/@test as "newTest")
        return $c'
                PASSING a.oldXml as "a" ,b.oldXml2 as "b" RETURNING CONTENT)  newXml
   FROM myXml a
   JOIN myXml2 b
   ON a.id = b.id;

newXml中所需的输出是:

<users>
        <user test="newTest">
           <userid>id1</userid>
           <name>dave</name>
        </user>
       <user>
           <userid>id2</userid>
           <name>steve</name>
      </user>
</users>

1 个答案:

答案 0 :(得分:1)

您需要首先执行let并为其提供自己的return子句,您可以在其中进行复制/修改:

SELECT oldXml, oldXml2,
  XMLQuery('
    let $newName := $b/users/user/name
    return 
      copy $c := $a
      modify (rename node $c/users/user/@test as "newTest")
      return $c'
  PASSING a.oldXml as "a", b.oldXml2 as "b" RETURNING CONTENT) newXml
FROM myXml a
JOIN myXml2 b
ON a.id = b.id;

然后,您可以在复制/修改部分中引用$newName,但不清楚您想如何使用它;或者为什么你想要那个变量而不是直接引用$b/users/user/name,除非你的真实代码在for循环中。

您不需要let来执行您想要的操作,您可以直接插入$b/users/user节点;使用XMLSerialize只是为了格式化输出:

SELECT oldXml, oldXml2,
  XMLSerialize(CONTENT XMLQuery('
    copy $c := $a
    modify (rename node $c/users/user/@test as "newTest",
      insert nodes $b/users/user after $c/users/user)
    return $c'
  PASSING a.oldXml as "a", b.oldXml2 as "b" RETURNING CONTENT)
  AS VARCHAR2(4000) INDENT SIZE=2) newXml
FROM myXml a
JOIN myXml2 b
ON a.id = b.id;

OLDXML                         OLDXML2                        NEWXML                        
------------------------------ ------------------------------ ------------------------------
<users>                        <users>                        <users>                       
  <user test="oldvalue">         <user>                         <user newTest="oldvalue">   
   <userid>id1</userid>           <userid>id2</userid>            <userid>id1</userid>      
   <name>dave</name>              <name>steve</name>              <name>dave</name>         
  </user>                        </user>                        </user>                     
</users>                       </users>                         <user>                      
                                                                  <userid>id2</userid>      
                                                                  <name>steve</name>        
                                                                </user>                     
                                                              </users>                      

如果您添加let,可以使用return,如答案的第一部分所示,但不确定它在此示例中获得了什么 - 也许它在您的真实场景中更有用 - 制作Xquery:

let $newUser := $b/users/user
return
  copy $c := $a
  modify (rename node $c/users/user/@test as "newTest",
    insert nodes $newUser after $c/users/user)
  return $c