Удаление нескольких узлов в поле SQL Server XML - PullRequest
1 голос
/ 06 октября 2011

Если вы запустите этот скрипт в SQL Server 2005:

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" />

Есть ли способ удалить несколько узлов в одном запросе? В частности, я хочу удалить все узлы, которые соответствуют критериям, из столбца в другой таблице (в этом примере t создается на лету, но с такой же легкостью он мог бы быть реальной таблицей).

1 Ответ

3 голосов
/ 07 октября 2011

Вы можете сделать 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
...