SQL:递归更新表中的 xml 列
Posted
技术标签:
【中文标题】SQL:递归更新表中的 xml 列【英文标题】:SQL: Update xml column in a table recursively 【发布时间】:2021-12-12 01:43:44 【问题描述】:我在 sql server 2012 中有一个表
具有以下列定义
CREATE TABLE [dbo].[tblStepList](
[ToDoId] [int] IDENTITY(1,1) NOT NULL,
[Data] [xml] NOT NULL
并且数据列是xml与
<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>'
我想用我的新 xml 更新表格的每一行,以便在 TextReading 名称之后使用名为 TextReadingId 的新节点来查看
我想插入一个名为 TextReadingId 的新节点我希望我的 TextReadingId 值是如下的运行数字
<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>1</TextReadingId>
</Step>
</Steplist>';
这是我尝试过的,但没有按预期工作
DECLARE @i int;
SELECT
@i = s.data.value('count(/Steplist/Step)', 'nvarchar(max)')
FROM tblStepList s
SET data.modify('insert <TextReadingId>sql:variable("@i")</TextReadingId> as last into (/Steplist/Step[sql:variable("@i")])[1]')
print @i
End
【问题讨论】:
<TextReadingId>
元素值只是一个流水号吗?
您使用的是哪个 dbms?
是一个流水号。我正在使用 sql server
提问时,您需要提供minimal reproducible example: (1) DDL 和样本数据填充,即 CREATE 表和 INSERT T-SQL 语句。 (2) 你需要做什么,即逻辑和你的代码尝试在 T-SQL 中实现它。 (3) 期望的输出,基于上述#1 中的样本数据。 (4) 您的 SQL Server 版本 (SELECT @@version;)。
@YitzhakKhabinsky Khabinsky 我刚刚更新了它
【参考方案1】:
请尝试以下解决方案。
它正在使用 XQuery 及其 FLWOR 表达式。
SQL
USE tempdb;
GO
DROP TABLE IF EXISTS [dbo].[tblStepList];
CREATE TABLE [dbo].[tblStepList](
[ToDoId] [int] IDENTITY(1,1) NOT NULL,
[Data] [xml] NOT NULL
);
INSERT INTO dbo.tblStepList ([Data]) VALUES
(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>');
-- before
SELECT * FROM dbo.tblStepList;
UPDATE dbo.tblStepList
SET [Data] = [Data].query('<Steplist>
for $x in /Steplist/Step
let $pos := count(Steplist/*[. << $x]) + 1
return <Step>$x/*,
if (not($x/TextReadingId)) then <TextReadingId>$pos</TextReadingId>
else ()
</Step>
</Steplist>');
-- after
SELECT * FROM dbo.tblStepList;
【讨论】:
我刚刚更新了我的问题 我可以通过使用 FLWOR 从辅助表中获取值吗?插入流水号 所以你在比赛中途改变了球门柱。我没有看到使用其他表格代替运行数字的简单方法。 我将问题恢复到原来的位置并问了另一个问题***.com/questions/69728769/… @Yitzhak Khabinsky 你能查一下***.com/q/69843694/3038042以上是关于SQL:递归更新表中的 xml 列的主要内容,如果未能解决你的问题,请参考以下文章
PL/SQL 使用一张表中的列数据更新表,基于不同表之间的相等性