用XML列[T-SQL]中的不同值更新所有行
我想更新ColumntUpdate,它是XML类型,存在于一个表SomeTable中。我想在每一行中放入包含新GUID列表的XML 我知道如何通过插入XML来更新XML,但我不知道如何为每一行创建新的GUID。当我在T-SQL->中将GUID分配给某个变量时,在not work cause中,它将是相同的值用XML列[T-SQL]中的不同值更新所有行,sql,sql-server,xml,Sql,Sql Server,Xml,我想更新ColumntUpdate,它是XML类型,存在于一个表SomeTable中。我想在每一行中放入包含新GUID列表的XML 我知道如何通过插入XML来更新XML,但我不知道如何为每一行创建新的GUID。当我在T-SQL->中将GUID分配给某个变量时,在not work cause中,它将是相同的值 UPDATE SomeTable SET ColumnToUpdate.modify('insert <SomeTag>, <ID Value=sql:variable
UPDATE SomeTable
SET ColumnToUpdate.modify('insert
<SomeTag>,
<ID Value=sql:variable(NEWID())/ID>,
<SomeOtherTag>MySpecificValue1</SomeOtherTag>,
<Tag3>True</Tag>,
</SomeTag>,
<SomeTag>
<ID Value=sql:variable(NEWID())/ID>,
<SomeOtherTag>MySpecificValueTotallyDiffrent</SomeOtherTag>,
<Tag3>False</Tag>,
</SomeTag>
<SomeTag>
<ID Value=sql:variable(NEWID())/ID>,
<SomeOtherTag>SomeOtherName</SomeOtherTag>,
<Tag3>False</Tag>,
</SomeTag>
<SomeTag>
<ID Value=sql:variable(NEWID())/ID>,
<SomeOtherTag>SomeOtherOtherName</SomeOtherTag>
<Tag3>False</Tag>
</SomeTag>
(/SomeParentTag/childTag)[1]')
以前
<someParentTag>
</childTag>
</someParentTag>
之后
这个guid必须是唯一的,其他行也必须是唯一的。您可以使用另一个表来生成所需数量的节点并插入它们。以下是一个例子:
declare @t table (
Id int identity(1,1) primary key,
XMLData xml
);
insert into @t (XMLData)
values ('<someParentTag>
<childTag/>
</someParentTag>'),
('<someParentTag>
<childTag/>
</someParentTag>');
declare @extradata table (
SomeOtherColumn varchar(100),
Column3 varchar(10)
);
-- Your data should come from somewhere, right?
insert into @extradata (SomeOtherColumn, Column3)
values
('MySpecificValue1', 'True'),
('MySpecificValueTotallyDiffrent', 'False'),
('SomeOtherName', 'False'),
('SomeOtherOtherName', 'False');
-- Before
select * from @t;
update t set XMLData.modify('insert sql:column("n.a") into (/someParentTag/childTag)[1]')
from @t t
cross apply (
select newid() as [ID/@Value], xd.SomeOtherColumn as [SomeOtherTag],
xd.Column3 as [Tag3]
from @extradata xd
-- Artificial correlation to prevent result caching
inner join @t tc on 1=1
where tc.Id = t.Id
for xml path('SomeTag'), type
) n(a);
-- After
select * from @t;
子查询中的关联是人为的,在本例中没有任何意义,但是似乎有必要防止SQL Server为自己节省一些工作,并对修改表中的所有行重新使用相同的XML片段。在您的实际案例中,如果您已经有某种关联,例如,生成的XML在任何方面都取决于您的主表,那么它应该足够了。我没有太具体地说明为什么编辑我的问题,请检查它。当我尝试使用您的示例时,我收到一个错误,XML实例仅支持作为使用sql:column/sql:varialbe的插入的直接源,但感谢您的支持help@dummyking,您正在使用SQL Server 2005吗?2008年首次实现了通过modify方法插入XML片段。如果是这样,我强烈建议您升级,因为您运行的是不受支持的版本。此外,检查数据库的兼容性级别也是有意义的,它应该是100或更高。我的示例适用于2016年,应该可以追溯到2008年。更新了答案以反映您的更改。@dummyking,更新了答案。如何生成行集并不重要——在我的示例中,您可以使用包含所有这些值的另一个表@extradata。的确,非常有趣。SQLServer计算插入的XML片段一次,然后对所有行重用它。我已经添加了一个与主表的关联来打破这一点。执行计划当然会更糟糕,但它仍然应该比任何循环都好。我希望是这样。
declare @t table (
Id int identity(1,1) primary key,
XMLData xml
);
insert into @t (XMLData)
values ('<someParentTag>
<childTag/>
</someParentTag>'),
('<someParentTag>
<childTag/>
</someParentTag>');
declare @extradata table (
SomeOtherColumn varchar(100),
Column3 varchar(10)
);
-- Your data should come from somewhere, right?
insert into @extradata (SomeOtherColumn, Column3)
values
('MySpecificValue1', 'True'),
('MySpecificValueTotallyDiffrent', 'False'),
('SomeOtherName', 'False'),
('SomeOtherOtherName', 'False');
-- Before
select * from @t;
update t set XMLData.modify('insert sql:column("n.a") into (/someParentTag/childTag)[1]')
from @t t
cross apply (
select newid() as [ID/@Value], xd.SomeOtherColumn as [SomeOtherTag],
xd.Column3 as [Tag3]
from @extradata xd
-- Artificial correlation to prevent result caching
inner join @t tc on 1=1
where tc.Id = t.Id
for xml path('SomeTag'), type
) n(a);
-- After
select * from @t;