0

在下面的代码中,我尝试将 oldXml2 中的“name”元素插入 oldXml,并将 oldXml 中的“test”属性值更新为“newTest”,结果组合输出为 newXml。代码成功更改了属性值,但是,当我添加:

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

从 oldXml2 获取名称元素的子句停止工作。有没有人可以解决这个问题?

我正在使用 Oracle 11g,它使用 xquery 1.0。

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>
4

1 回答 1

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循环中。


不需要 alet做自己想做的事,$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如果您添加 a ,您可以使用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
于 2016-11-02T10:20:25.353 回答