Sql server 用变量替换XML节点元素
我目前有以下代码在名为PARTY的父节点下创建XML。参与方节点内是另一个称为角色的节点。我的问题是如何用xquery中的[SequenceNr]变量替换当前的角色节点,该节点仅表示角色 我曾尝试在@OutputXml中进行替换,但没有成功,我认为在xquery中应该有一种简单的方法,我不知道 当前代码:Sql server 用变量替换XML节点元素,sql-server,xml,sql-server-2008,xquery,Sql Server,Xml,Sql Server 2008,Xquery,我目前有以下代码在名为PARTY的父节点下创建XML。参与方节点内是另一个称为角色的节点。我的问题是如何用xquery中的[SequenceNr]变量替换当前的角色节点,该节点仅表示角色 我曾尝试在@OutputXml中进行替换,但没有成功,我认为在xquery中应该有一种简单的方法,我不知道 当前代码: WITH [PartyNodes] AS ( SELECT ( SELECT [dbo].[X
WITH [PartyNodes] AS
(
SELECT (
SELECT [dbo].[XmlA](@Id),
[dbo].[XmlB](@Id)
FOR XML PATH(''),TYPE
) AS [AllTogether]
)
,[NumberedSequences] AS
(
SELECT 'PARTY' + CONVERT(NVARCHAR, ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) + 10) + '_ROLE1' AS [PartySequenceNr], -- party label
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) + 10 AS [SequenceNr], -- party sequence
[T].[Party].[query]('.') AS [TheNode]
FROM [PartyNodes]
CROSS APPLY [AllTogether].[nodes]('/PARTY') AS T(Party)
)
SELECT @OutputXml = ( SELECT [TheNode].[query]('let $p:=/PARTY[1]
let $lbl:=sql:column("PartySequenceNr")
let $nr:=sql:column("SequenceNr")
return
<PARTY SequenceNumber="{$nr}" xlink_label="{$lbl}" >
{$p/*}
</PARTY>'
)
FROM [NumberedSequences]
FOR XML PATH(''),ROOT('PARTIES')
);
电流输出:
<PARTY SequenceNumber="1" xlink:label="PARTY1_ROLE1">
<INDIVIDUAL>
<NAME>
<FullName>Test</FullName>
</NAME>
</INDIVIDUAL>
<ROLES>
<ROLE>
<A>Test</A>
</ROLE>
</ROLES>
</PARTY>
期望输出:
<PARTY SequenceNumber="1" xlink:label="PARTY1_ROLE1">
<INDIVIDUAL>
<NAME>
<FullName>Test</FullName>
</NAME>
</INDIVIDUAL>
<ROLES>
<ROLE SequenceNumber="1" xlink:label="PARTY1_ROLE1">>
<A>Test</A>
</ROLE>
</ROLES>
</PARTY>
我试着跟随你的想法,但不能 有两个函数XmlA和XmlB。首先,将它们的结果合并到一起。稍后您将使用.nodes'/PARTY'从中读取,但是您显示的XML只有一个PARTY节点作为根节点 此外,还可以使用FLWOR XQuery插入两个属性。但我怀疑,xlink_标签是否会显示为xlink:label 您显示的XML不能是上述操作的结果。。。或者我错过了什么 我的第一个想法是:这似乎太复杂了。。。如果以下情况没有帮助,请提供有关您的目标的更多详细信息,请尝试。这可能是 我从没有属性的XML开始,假设这是前面讨论的结果:
DECLARE @xml XML=
N'<PARTY>
<INDIVIDUAL>
<NAME>
<FullName>Test</FullName>
</NAME>
</INDIVIDUAL>
<ROLES>
<ROLE>
<A>Test</A>
</ROLE>
</ROLES>
</PARTY>';
结果是:
<PARTY SequenceNumber="PARTY1_ROLE1" xlink_label="1">
<INDIVIDUAL>
<NAME>
<FullName>Test</FullName>
</NAME>
</INDIVIDUAL>
<ROLES>
<ROLE SequenceNumber="PARTY1_ROLE1" xlink_label="1">
<A>Test</A>
</ROLE>
</ROLES>
</PARTY>
结果
<PARTY SequenceNumber="PARTY1_ROLE1" xmlns:xlink="DummyUrl" xlink:label="1">
<INDIVIDUAL>
<NAME>
<FullName>Test</FullName>
</NAME>
</INDIVIDUAL>
<ROLES>
<ROLE SequenceNumber="PARTY1_ROLE1" xlink:label="1">
<A>Test</A>
</ROLE>
</ROLES>
</PARTY>
哇,太棒了。这有多高效?或者我该如何测试它的性能。事实上,我以不同的方式结束了这一切。我创建了一个表类型,在其中插入了我的标签和一些其他信息,然后将该变量类型传递给我的参与方函数,并从中选择特定的记录。@DrockClimper,基本上可以使用DECLARE@d DATETIME=GETDATE测试性能;剂量测定法;选择CASTGETDATE-@d作为时间;但这种方法肯定不是最好的。。。创建XML只是为了通过一些FLWOR XQuery将其按下一定很慢。。。你的事情闻起来太复杂了,但我不知道任何细节。如前所述,即使提供的信息也不一致……你能为我澄清一下吗。在if条件下检查角色值之前,您在哪里指定$nd保存角色值?@drockclimper此行负责$p中的$nd:for$nd/*这将读取$p中的所有子节点。向下操作for循环会将每个子节点依次移动到$nd中。节点角色需要一个不同的处理,因此if使用本地名称进行检查。
SELECT @xml.query
(N' declare namespace xlink="DummyUrl";
let $p:=/PARTY[1]
let $lbl:=sql:variable("@PartySequenceNr")
let $nr:=sql:variable("@SequenceNr")
return
<PARTY SequenceNumber="{$nr}" xlink:label="{$lbl}" >
{
for $nd in $p/*
return
if(local-name($nd)="ROLES") then
(
<ROLES><ROLE SequenceNumber="{$nr}" xlink:label="{$lbl}" >
{$nd/ROLE/*}
</ROLE></ROLES>
)
else $nd
}
</PARTY>
')
<PARTY SequenceNumber="PARTY1_ROLE1" xmlns:xlink="DummyUrl" xlink:label="1">
<INDIVIDUAL>
<NAME>
<FullName>Test</FullName>
</NAME>
</INDIVIDUAL>
<ROLES>
<ROLE SequenceNumber="PARTY1_ROLE1" xlink:label="1">
<A>Test</A>
</ROLE>
</ROLES>
</PARTY>