答案 0 :(得分:2)
假设您有以下数据:
并且您想要删除记录2.1
及其所有后代(仅在此情况下为2.1.3
)。您可以使用以下代码获取需要删除的IDs
:
WITH DataSource ([ID], [HierarchyLevel]) AS
(
SELECT [ID]
,CAST(REPLACE('/' + [Name] + '/', '.', '/') AS HIERARCHYID)
FROM @DataSource
)
SELECT [ID]
,[HierarchyLevel].ToString()
FROM DataSource
WHERE [HierarchyLevel].IsDescendantOf('/2/1/') = 1;
基本上,我们会将您的记录转换为hierarchy id
类型,并使用内置IsDescendantOf函数获取该节点的所有childs
。
这是完整的工作示例:
DECLARE @DataSource TABLE
(
[ID] TINYINT
,[Name] VARCHAR(12)
,[Owner] VARCHAR(12)
,[Parent] INT
);
INSERT INTO @DataSource ([ID], [Name], [Owner], [Parent])
VALUES (1, '1', '1', NULL)
,(2, '1.1', '1.1', 1)
,(3, '1.1.1', '1.1.1', 2)
,(4, '2', '2.1', NULL)
,(5, '2.1', '2.1', 4)
,(6, '2.2', '2.2', 4)
,(7, '2.1.3', '2.1.3', 5);
WITH DataSource ([ID], [HierarchyLevel]) AS
(
SELECT [ID]
,CAST(REPLACE('/' + [Name] + '/', '.', '/') AS HIERARCHYID)
FROM @DataSource
)
DELETE @DataSource
FROM @DataSource DS
INNER JOIN DataSource DS1
ON DS.[ID] = DS1.[ID]
WHERE [HierarchyLevel].IsDescendantOf('/2/1/') = 1;
SELECT *
FROM @DataSource;
答案 1 :(得分:2)
这可以使用递归公用表表达式完成。
要获得一个节点的所有孩子,您可以使用:
with tree as (
select id, parent
from eyalewin
where id = 1
union all
select c.id, c.parent
from eyalewin c
join tree p on p.id = c.parent
)
select *
from tree;
然后可以用它来删除所有这些:
with tree as (
select id, parent
from eyalewin
where id = 1
union all
select c.id, c.parent
from eyalewin c
join tree p on p.id = c.parent
)
delete from eyalewin
where id in (select id
from tree);