2

次のような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」に等しいすべての行を見つけて、「John」を「Jon」に置き換える必要があります。私の xml は nvarchar(max) 列に格納されているため、列を xml 変数にキャストして使用できる関数を作成しています。私が理解できないのは、どの「アイテム」が一致するかを見つける方法と、その1つの値(つまり、「ジョン」のみ)を置き換える方法です。

私はSQLサーバー2008を使用しています。

4

1 に答える 1

3

次の MSDN 記事を参照してください。

(XML DML)の値を置換

具体的には、次のようなことを試してください。

-- 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
于 2012-04-09T19:34:41.413 に答える