替换存储在 SQL Server 数据库列中的 XML 中的节点名称
我想知道如何替换存储在 SQL Server 数据库中的 xml 中的子节点名称
I'd like to know how I can replace a child node name in a xml that I stored in my SQL Server database
示例 XML
<CompanyStatus>
<ProductionServers>
<ProductionServer>
<Patch>0</Patch>
<Status>Green</Status>
<Test_Node>Yes</Test_Node>
</ProductionServers>
</ProductionServer>
</CompanyStatus>
我将如何将其更改为以下内容:
How would I change that to the following:
<CompanyStatus>
<ProductionServers>
<ProductionServer>
<Patch>0</Patch>
<Status>Green</Status>
<Live_Node>Yes</Live_Node>
</ProductionServers>
</ProductionServer>
</CompanyStatus>
基本上唯一的变化是
被重命名为
但值是相同的.
Where essentially the only change is <Test_Node>
is renamed to <Live_Node>
but the value is the same.
有没有简单的方法可以做到这一点?
Is there a simple way to do this?
我的数据库中有大约 1000 条记录
I have about 1000 records in my database
推荐答案
这是我的建议
- 使用属性保存
- 容忍元素的位置(只要这个元素是唯一的)
检查一下:
DECLARE @xml XML=
N'<CompanyStatus>
<ProductionServers>
<ProductionServer>
<Patch>0</Patch>
<Status>Green</Status>
<Test_Node a="x" b="y" c="z">Yes</Test_Node>
</ProductionServer>
</ProductionServers>
</CompanyStatus>';
--这将创建带有新元素名称
的
及其所有属性(如果有):
--This will create the <Test_Node>
with all its attributes (if there are any) with the new element name <Live_Node>
:
DECLARE @NewNode XML=
(
SELECT @xml.query(N'let $nd:=(//*[local-name()="Test_Node"])[1]
return
<Live_Node> {$nd/@*}
{$nd/text()}
</Live_Node>
')
);
--这将首先在原始之后直接插入"@NewNode"
,并将删除原始:
--this will first insert the "@NewNode"
directly after the original, and will remove the original:
SET @xml.modify(N'insert sql:variable("@NewNode") after (//*[local-name()="Test_Node"])[1]');
SET @xml.modify(N'delete (//*[local-name()="Test_Node"])[1]');
SELECT @xml;
结果
<CompanyStatus>
<ProductionServers>
<ProductionServer>
<Patch>0</Patch>
<Status>Green</Status>
<Live_Node a="x" b="y" c="z">Yes</Live_Node>
</ProductionServer>
</ProductionServers>
</CompanyStatus>
更新:与使用可更新 CTE 的表格数据相同:
DECLARE @xmlTable TABLE (YourXml XML);
INSERT INTO @xmlTable VALUES
(--Test_Node has got attributes
N'<CompanyStatus>
<ProductionServers>
<ProductionServer>
<Patch>0</Patch>
<Status>Green</Status>
<Test_Node a="x" b="y" c="z">Yes</Test_Node>
</ProductionServer>
</ProductionServers>
</CompanyStatus>'
)
,( --different position, no attributes
N'<CompanyStatus>
<ProductionServers>
<Test_Node>Yes</Test_Node>
<ProductionServer>
<Patch>0</Patch>
<Status>Green</Status>
</ProductionServer>
</ProductionServers>
</CompanyStatus>'
)
,( --No test node at all
N'<CompanyStatus>
<ProductionServers>
<ProductionServer>
<Patch>0</Patch>
<Status>Green</Status>
</ProductionServer>
</ProductionServers>
</CompanyStatus>'
);
--可更新的 CTE 返回原始节点和新节点.这可以一次性更新:
--the updateable CTE returns the original and the new node. This can be updated in one go:
WITH ReadNode AS
(
SELECT t.YourXml.query(N'let $nd:=(//*[local-name()="Test_Node"])[1]
return
<Live_Node> {$nd/@*}
{$nd/text()}
</Live_Node>
') AS NewNode
,t.YourXml AS Original
FROM @xmlTable AS t
)
UPDATE ReadNode SET Original.modify(N'insert sql:column("NewNode") after (//*[local-name()="Test_Node"])[1]');
UPDATE @xmlTable SET YourXml.modify(N'delete (//*[local-name()="Test_Node"])[1]');
SELECT *
FROM @xmlTable
相关文章