재귀가 효율성을 위해 항상 좋은 것은 아니지만 이러한 문제를 해결하는 방법 중 하나입니다. node_table에 고유 한 필드 node_id (int)가 있다고 가정합니다.
declare @start_node_id int, @loop_limit int, @loop_count int;
set @start_node_id = 1234; -- Insert the node ID you want to start from.
set @loop_limit = 1000; -- Set a limit on the number of loop iterations.
set @loop_count = 0;
create table #NODES_TO_DELETE(NODE_ID int);
-- Get first child nodes, directly linked to start node.
insert into #NODES_TO_DELETE(NODE_ID)
select A.NODE_ID
from node_table A inner join node_table B on B.from_section = A.to_section
where B.NODE_ID = @start_node_id;
-- If there are child nodes not yet in our temp table, continue loop.
WHILE EXISTS(select 1
from node_table A inner join node_table B on B.from_section = A.to_section
inner join #NODES_TO_DELETE D on B.NODE_ID = D.NODE_ID
left join #NODES_TO_DELETE X on A.NODE_ID = X.NODE_ID
where X.NODE_ID is null) and
@loop_count < @loop_limit
BEGIN
-- Add child nodes to temp table. Avoid duplicate IDs.
insert into #NODES_TO_DELETE(NODE_ID)
select distinct A.NODE_ID
from node_table A inner join node_table B on B.from_section = A.to_section
inner join #NODES_TO_DELETE D on B.NODE_ID = D.NODE_ID
left join #NODES_TO_DELETE X on A.NODE_ID = X.NODE_ID
where X.NODE_ID is null;
-- Increment loop count.
set @loop_count = @loop_count + 1;
END
IF @loop_count > @loop_limit
print 'Loop limit exceeded.'; -- We've exceeded our loop limit. May not have all matches.
ELSE
delete N -- Delete all nodes inserted into our temp table.
from node_table N
inner join #NODES_TO_DELETE D on N.NODE_ID = D.NODE_ID;
drop table #NODES_TO_DELETE;