在下面的代码中,我试图插入"名称"从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>
答案 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