在 Oracle XMLQuery 中组合 "Transform" 和 FLWOR 表达式
Combining "Transform" and FLWOR expressions in Oracle XMLQuery
在下面的代码中,我试图将 oldXml2 中的 "name" 元素插入到 oldXml 中,并将 oldXml 中的 "test" 属性值更新为 "newTest",得到的组合输出是新的XML。
代码成功更改了属性值但是,当我添加:
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>
您需要先执行 let
并为其提供自己的 return
子句,然后在其中执行 copy/modify:
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;
然后您可以参考 copy/modify 部分中的 $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>
如果你添加一个 return
,你可以使用 let
,就像答案的第一部分一样,但不确定它在这个例子中对你有什么好处 - 也许它在你的实际中更有用场景 - 制作 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
在下面的代码中,我试图将 oldXml2 中的 "name" 元素插入到 oldXml 中,并将 oldXml 中的 "test" 属性值更新为 "newTest",得到的组合输出是新的XML。 代码成功更改了属性值但是,当我添加:
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>
您需要先执行 let
并为其提供自己的 return
子句,然后在其中执行 copy/modify:
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;
然后您可以参考 copy/modify 部分中的 $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>
如果你添加一个 return
,你可以使用 let
,就像答案的第一部分一样,但不确定它在这个例子中对你有什么好处 - 也许它在你的实际中更有用场景 - 制作 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