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是一个自引用的公共表表达式,它的设计之一是专门处理分层数据。