Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
sql:删除子树表(id、Parentid),删除一个项目及其所有子项_Sql_Sql Server - Fatal编程技术网

sql:删除子树表(id、Parentid),删除一个项目及其所有子项

sql:删除子树表(id、Parentid),删除一个项目及其所有子项,sql,sql-server,Sql,Sql Server,我有一张这样的桌子 foo(id, parentId) -- there is a FK constraint from parentId to id 我需要删除一个项目,包括他的所有孩子和孩子的孩子等等。 有人知道怎么做吗?您可以编写一个,锚定将是初始Id。好吧,SQL SERVER不喜欢层次关系的级联删除。因此,您可以像前面提到的那样执行CTE,也可以像这样使用递归触发器执行解决方案。但我想,CTE更容易 请参阅,以下是使用CTE的解决方案: CREATE PROC deleteFoo

我有一张这样的桌子

foo(id, parentId) 
-- there is a FK constraint from parentId to id
我需要删除一个项目,包括他的所有孩子和孩子的孩子等等。 有人知道怎么做吗?

您可以编写一个,锚定将是初始Id。

好吧,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
)

首先,我们定义递归CTE,然后从[Foo]表中从最高级的子记录开始删除记录;因此,在最后一轮中,顶部节点将被删除。

顶部100%的内容是什么?它只删除前100行吗?@Omu,不。前100%是指所有记录。如果没有它,您将得到ORDERBY子句在视图、内联函数、派生表、子查询和公共表表达式中无效,除非还指定了TOP或FOR XML。错误所以这只是一个解决方法,我相信子查询中的ORDERBY是多余的。从节点N中选择N.[Id]也可以实现同样的效果。我不认为有最后删除顶层的概念。所有行都会同时删除,即使它们不是,您也只对IN子句的参数排序,而不是DELETE。当将排序顺序更改为ASC时,我的测试没有导致FK冲突,因此我相信它确认了内部select是冗余的。同意,order BY在DELETE语句中是冗余的,除非不是在具有某种奇特逻辑的游标中,直接取决于要删除的项的顺序。但看起来不错: