SQL:使用修改函数迭代xml个节点或如何递归插入或修改节点
SQL: Use modify function to iterate on xml nodes or How to insert or modify nodes recursively
我有一个xml,如下面的代码所示
我想遍历每个节点并在每个 TextReadingName 节点后插入一个节点
DECLARE @XML XML =
N'<Steplist>
<Step>
<StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
<Rank>1</Rank>
<IsComplete>false</IsComplete>
<TextReadingName>bug-8588_Updated3</TextReadingName>
</Step>
<Step>
<StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
<Rank>2</Rank>
<TextReadingName>reading1</TextReadingName>
</Step>
</Steplist>';
--SELECT x.XmlCol.value('(StepId)[1]', 'nvarchar(max)') as StepId
--FROM @xml.nodes('/Steplist/Step') x(XmlCol)
这就是我希望新 xml 的样子
N'<Steplist>
<Step>
<StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
<Rank>1</Rank>
<IsComplete>false</IsComplete>
<TextReadingName>bug-8588_Updated3</TextReadingName>
<TextReadingId>1</TextReadingId>
</Step>
<Step>
<StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
<Rank>2</Rank>
<TextReadingName>reading1</TextReadingName>
<TextReadingId>2</TextReadingId>
</Step>
</Steplist>';
我能够 select 如下所示的节点,但无法遍历每个节点并修改数据
--SELECT x.XmlCol.value('(StepId)[1]', 'nvarchar(max)') as StepId
--FROM @xml.nodes('/Steplist/Step') x(XmlCol)
我正在寻找与上面相同的功能,但用于插入节点
这就是我希望我的新 xml 在 TextReading 名称
之后使用名为 TextReadingId 的新节点来查看的方式
N'<Steplist>
<Step>
<StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
<Rank>1</Rank>
<IsComplete>false</IsComplete>
<TextReadingName>bug-8588_Updated3</TextReadingName>
<TextReadingId>1</TextReadingId>
</Step>
<Step>
<StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
<Rank>2</Rank>
<TextReadingName>reading1</TextReadingName>
<TextReadingId>2</TextReadingId>
</Step>
</Steplist>';
您可以将 modify
与 insert
一起使用,但主要缺点似乎是 SQL 服务器仅允许 insert
进入单个节点,我不能将它与 FLOWR 表达式结合起来,所以我不得不使用 SQL WHILE 循环来执行各种 modify
调用:
DECLARE @XML XML =
N'<Steplist>
<Step>
<StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
<Rank>1</Rank>
<IsComplete>false</IsComplete>
<TextReadingName>bug-8588_Updated3</TextReadingName>
</Step>
<Step>
<StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
<Rank>2</Rank>
<TextReadingName>reading1</TextReadingName>
</Step>
</Steplist>';
BEGIN
DECLARE @i int;
SELECT @i = @XML.value('count(Steplist/Step)', 'int');
WHILE @i > 0
BEGIN
SET @XML.modify('insert <TextReadingId>{sql:variable("@i")}</TextReadingId> as last into (/Steplist/Step[sql:variable("@i")])[1]');
SET @i = @i - 1;
END
END
SELECT @XML;
我有一个xml,如下面的代码所示
我想遍历每个节点并在每个 TextReadingName 节点后插入一个节点
DECLARE @XML XML =
N'<Steplist>
<Step>
<StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
<Rank>1</Rank>
<IsComplete>false</IsComplete>
<TextReadingName>bug-8588_Updated3</TextReadingName>
</Step>
<Step>
<StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
<Rank>2</Rank>
<TextReadingName>reading1</TextReadingName>
</Step>
</Steplist>';
--SELECT x.XmlCol.value('(StepId)[1]', 'nvarchar(max)') as StepId
--FROM @xml.nodes('/Steplist/Step') x(XmlCol)
这就是我希望新 xml 的样子
N'<Steplist>
<Step>
<StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
<Rank>1</Rank>
<IsComplete>false</IsComplete>
<TextReadingName>bug-8588_Updated3</TextReadingName>
<TextReadingId>1</TextReadingId>
</Step>
<Step>
<StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
<Rank>2</Rank>
<TextReadingName>reading1</TextReadingName>
<TextReadingId>2</TextReadingId>
</Step>
</Steplist>';
我能够 select 如下所示的节点,但无法遍历每个节点并修改数据
--SELECT x.XmlCol.value('(StepId)[1]', 'nvarchar(max)') as StepId
--FROM @xml.nodes('/Steplist/Step') x(XmlCol)
我正在寻找与上面相同的功能,但用于插入节点
这就是我希望我的新 xml 在 TextReading 名称
之后使用名为 TextReadingId 的新节点来查看的方式N'<Steplist>
<Step>
<StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
<Rank>1</Rank>
<IsComplete>false</IsComplete>
<TextReadingName>bug-8588_Updated3</TextReadingName>
<TextReadingId>1</TextReadingId>
</Step>
<Step>
<StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
<Rank>2</Rank>
<TextReadingName>reading1</TextReadingName>
<TextReadingId>2</TextReadingId>
</Step>
</Steplist>';
您可以将 modify
与 insert
一起使用,但主要缺点似乎是 SQL 服务器仅允许 insert
进入单个节点,我不能将它与 FLOWR 表达式结合起来,所以我不得不使用 SQL WHILE 循环来执行各种 modify
调用:
DECLARE @XML XML =
N'<Steplist>
<Step>
<StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
<Rank>1</Rank>
<IsComplete>false</IsComplete>
<TextReadingName>bug-8588_Updated3</TextReadingName>
</Step>
<Step>
<StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
<Rank>2</Rank>
<TextReadingName>reading1</TextReadingName>
</Step>
</Steplist>';
BEGIN
DECLARE @i int;
SELECT @i = @XML.value('count(Steplist/Step)', 'int');
WHILE @i > 0
BEGIN
SET @XML.modify('insert <TextReadingId>{sql:variable("@i")}</TextReadingId> as last into (/Steplist/Step[sql:variable("@i")])[1]');
SET @i = @i - 1;
END
END
SELECT @XML;