sql:删除子树表(id,Parentid),删除所有孩子的项目

Omu*_*Omu 4 sql sql-server

我有一张这样的桌子

foo(id, parentId) 
-- there is a FK constraint from parentId to id
Run Code Online (Sandbox Code Playgroud)

我需要删除所有孩子和孩子的孩子等项目.谁知道怎么办?

Ale*_*lex 11

AFAIK,SQL SERVER不喜欢级联删除层级关系.所以,你可以做两CTE(如俄德提到的)或用递归触发溶液(不知何故像这样).但我想,CTE更容易.

看,这是使用CTE的解决方案:

CREATE PROC deleteFoo 
@id bigint
as
WITH Nodes ([Id], [ParentId], [Level]) 
AS (
    SELECT  F.[Id], F.[ParentId], 0 AS [Level]
    FROM    [dbo].Foo F
    WHERE   F.[Id] = @id

    UNION ALL

    SELECT  F.[Id], F.[ParentId], N.[Level] + 1
    FROM    [dbo].Foo F
        INNER JOIN Nodes N ON N.[Id] = F.[ParentId]
)

DELETE
FROM    Foo
WHERE   [Id] IN (
    SELECT  TOP 100 PERCENT N.[Id] 
    FROM    Nodes N
    ORDER BY N.[Level] DESC
)
Run Code Online (Sandbox Code Playgroud)

首先,我们定义递归CTE,然后从[Foo]子记录开始从表中删除记录(最高Level;因此,顶部节点将在最后一个回合中删除).

  • 我相信子查询中的顺序是多余的.使用(SELECT N. [Id] FROM Nodes N)也可以实现相同的目的.我不认为最后删除顶级的概念.所有行都会被同时删除,即使它们不是,您只按顺序排列IN子句的参数而不是DELETE.将排序顺序更改为ASC时,我的测试没有导致FK违规,所以我相信它确认内部选择是多余的. (2认同)