Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.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 删除表中引用自身的所有子项_Sql_Sql Server - Fatal编程技术网

Sql 删除表中引用自身的所有子项

Sql 删除表中引用自身的所有子项,sql,sql-server,Sql,Sql Server,假设我们有一张这样的桌子: CREATE TABLE Test ( Id INT NOT NULL PRIMARY KEY IDENTITY(1,1), [Name] NVARCHAR(50) NOT NULL, ParentId INT NULL FOREIGN KEY REFERENCES Test(Id) ) 在此表中,我们有一个数据层次结构,它可能类似于: INSERT INTO Test (Name) VALUES ('ABC'), ('DEF'), ('H

假设我们有一张这样的桌子:

CREATE TABLE Test
(
    Id INT NOT NULL PRIMARY KEY IDENTITY(1,1),
    [Name] NVARCHAR(50) NOT NULL,
    ParentId INT NULL FOREIGN KEY REFERENCES Test(Id)
)
在此表中,我们有一个数据层次结构,它可能类似于:

INSERT INTO Test (Name) 
VALUES ('ABC'), ('DEF'), ('HIJ');
GO

INSERT INTO TEST (Name, ParentId) 
VALUES ('KLM', 1), ('NOP', 1), ('QRS', 2), ('TUV', 2), ('XYX', 3)
GO

INSERT INTO Test (Name, ParentId) 
VALUES ('AAB', 4), ('AAC', 4), ('AAD', 4)

如何在不使用级联删除的情况下删除id 1及其所有子项?

您必须使用rCTE(递归公共表表达式)在层次结构中递归。然后,您可以
将该数据加入表并删除相关行:

DECLARE @ID int = 1;

WITH rCTE AS(
    SELECT T.Id
    FROM dbo.Test T
    WHERE T.Id = @ID
    UNION ALL
    SELECT T.Id
    FROM rCTE r
         JOIN dbo.Test T ON r.Id = T.ParentId)
DELETE T
FROM dbo.Test T
     JOIN rCTe r ON T.Id = r.Id;
请注意,与您可能看到的一些示例不同,例如使用CTE删除重复行时,rCTE是不可更新的(由于使用了
联合
)。因此,您不能简单地在末尾对CTE执行
DELETE
操作(
DELETE FROM rCTE
),您必须将其用作
JOIN


请您解释一下,我不明白这是怎么回事?我的开场白解释了这一点,@3xGuy:“您必须使用rCTE(递归公共表表达式)在层次结构中递归。然后您可以将该数据连接到表并删除相关行:”如果将
DELETE
更改为
SELECT
,则可以从rCTE返回数据@3xGuy。实际上,rCTe是一个自引用的公共表表达式,它的设计之一是专门处理分层数据。