我在表中包含一个包含xml的列,如下所示
<memberHours type="TeamHours[]">
<item>
<member type="String">Bill</member>
<hours type="Decimal">0.0</hours>
</item>
<item>
<member type="String">John</member>
<hours type="Decimal">0.0</hours>
</item>
<item>
<member type="String">Sally</member>
<hours type="Decimal">0.0</hours>
</item>
</memberHours>
我需要能够找到成员等于'John'的所有行,然后用'Jon'替换'John'。由于我的xml存储在nvarchar(max)列中,我正在编写一个函数,将列转换为我可以使用的xml变量。我无法弄清楚的是如何找到哪个'Item'匹配以及如何替换那个值(即只是'John')
我在SQL Server 2008上。
答案 0 :(得分:3)
查看以下MSDN文章:
具体来说,您可以尝试这样的事情:
-- Setup test data
declare @table table (
col nvarchar(max) not null
)
insert into @table select
'<memberHours type="TeamHours[]">
<item>
<member type="String">Bill</member>
<hours type="Decimal">0.0</hours>
</item>
<item>
<member type="String">John</member>
<hours type="Decimal">0.0</hours>
</item>
<item>
<member type="String">Sally</member>
<hours type="Decimal">0.0</hours>
</item>
</memberHours>'
-- Set search/replace vars
declare @oldval nvarchar(max) = 'John'
declare @newval nvarchar(max) = 'Jon'
declare @oldcol xml
declare @newcol xml
-- Loop over records fitting the search
while exists (
select null
from (
select cast(col as xml) as col
from @table
) as a
where col.exist('/memberHours/item/member[(text()[1]) eq sql:variable("@oldval")]') = 1
) begin
-- Grab a record as xml
set @oldcol = (
select top 1 col
from (
select cast(col as xml) as col
from @table
) as a
where col.exist('/memberHours/item/member[(text()[1]) eq sql:variable("@oldval")]') = 1
)
set @newcol = @oldcol
-- Modify xml data
while @newcol.exist('/memberHours/item/member[(text()[1]) eq sql:variable("@oldval")]') = 1 begin
set @newcol.modify('
replace value of (/memberHours/item[member=sql:variable("@oldval")]/member/text())[1] with sql:variable("@newval")
')
end
-- Update table
update @table
set col = cast(@newcol as nvarchar(max))
where cast(cast(col as xml) as nvarchar(max)) = cast(@oldcol as nvarchar(max)) -- Cast both for equality test!
end
-- Test output
select * from @table