2011-10-06 43 views
1

如果您運行在SQL Server 2005中此腳本:刪除在SQL Server中的XML領域的多個節點

create table #xmltemp 
(
    id int, 
    data xml null 
) 

insert into #xmltemp 
select 1, '' 

update #xmltemp 
set data.modify('insert <a id="1" /> into /') 
update #xmltemp 
set data.modify('insert <a id="2" /> into /') 
update #xmltemp 
set data.modify('insert <a id="3" /> into /') 
update #xmltemp 
set data.modify('insert <a id="4" /> into /') 

select * from #xmltemp 

update x 
set data.modify('delete //a[@id=sql:column("t.xmlid")]') 
from #xmltemp x 
inner join (
    select 1 as id, 1 as xmlid union 
    select 1 as id, 2 as xmlid union 
    select 1 as id, 3 as xmlid 
) t on t.id = x.id 

select * from #xmltemp 

drop table #xmltemp 

您將得到以下輸出:

id data 
1 <a id="1" /><a id="2" /><a id="3" /><a id="4" /> 

id data 
1 <a id="2" /><a id="3" /><a id="4" /> 

我希望它刪除所有三個節點而不只是第一個,使第二個選擇返回:

id data 
1 <a id="4" /> 

有沒有辦法刪除多個點es在單個查詢中?具體來說,我想刪除所有與另一個表中的列匹配的條件的節點(在此示例中,t是即時創建的,但它可能很容易就是實際的表)。

回答

3

您可以從連接的查詢中將xmlid轉換爲逗號分隔的字符串,並在謂詞中使用該字符串。

create table #IdToDelete(id int, xmlid int) 
insert into #IdToDelete values (1, 1) 
insert into #IdToDelete values (1, 2) 
insert into #IdToDelete values (1, 3) 
insert into #IdToDelete values (2, 4) 

update x 
set data.modify('delete //a[contains(sql:column("t.xmlid"), @id)]') 
from #xmltemp x 
inner join (
    select D1.id, 
      (select ','+cast(D2.xmlid as varchar(10)) 
      from #IdToDelete as D2 
      where D1.id = D2.id 
      for xml path('')) as xmlid 
    from #IdToDelete as D1 
    group by D1.id 
) t on t.id = x.id 
+0

謝謝,這很接近我最終做的。我只是在子查詢中使用「for xml explicit」重建了xml。 – tloflin