Если нет внешних ключей, это сделает это.Я создаю пример таблицы с именами узлов с двумя столбцами, ID и Parent.В моей версии это целые числа, но это не имеет значения.
create table nodes(id int, parent int)
insert nodes values (1,null),(2,1),(3,1),(4,2),(5,null)
select * from nodes
Результат:
id parent
1 NULL
2 1
3 1
4 2
5 NULL
Создайте CTE, который пересекает отношения
declare @target int; set @target=2
;with cte as
(
select *, 1 as depth from nodes where id=@target
union all
select nodes.*, depth+1 from nodes
join cte on cte.id=nodes.parent
)
delete nodes where id in (select id from cte)
Это результат
select * from nodes
1 NULL
3 1
5 NULL
Если у вас есть внешние ключи, вам нужно будет просмотреть их с самой большой глубины до самой низкой, чтобы избежать ошибок.Это будет сделано (без курсора)
declare @temp table(id int, depth int)
declare @target int; set @target=2
;with cte as
(
select *, 1 as depth from nodes where id=@target
union all
select nodes.*, depth+1 from nodes
join cte on cte.id=nodes.parent
)
insert @temp
select id,depth from cte
while exists(select * from @temp)
begin
delete nodes from nodes
join @temp t on t.id=nodes.id
where depth=(select max(depth) from @temp)
delete @temp where depth=(select max(depth) from @temp)
end
Результат тот же.