我有一个非常简单的数据模型,代表树结构:
RootEntity
是此类树的根,它可以包含ContainerEntity
类型和AtomEntity
类型的子项。类型ContainerEntity
也可以包含ContainerEntity
类型和AtomEntity
类型的子项,但不能包含RootEntity
类型的子项。儿童以众所周知的顺序被引用。数据库模型如下所示。
我现在的问题是当我删除RootEntity
时,我想要递归删除所有孩子。我用CASCADE DELETE创建了外键,为此创建了两个删除触发器。但它并没有删除所有内容,它总是在ContainerEntity
,AtomEntity
,ContainerEntity_Children
和AtomEntity_Children
表格中留下一些内容。似乎从3的递归级别开始。
CREATE TABLE RootEntity
(
Id UNIQUEIDENTIFIER NOT NULL,
Name VARCHAR(500) NOT NULL,
CONSTRAINT PK_RootEntity PRIMARY KEY NONCLUSTERED (Id),
);
CREATE TABLE ContainerEntity
(
Id UNIQUEIDENTIFIER NOT NULL,
Name VARCHAR(500) NOT NULL,
CONSTRAINT PK_ContainerEntity PRIMARY KEY NONCLUSTERED (Id),
);
CREATE TABLE AtomEntity
(
Id UNIQUEIDENTIFIER NOT NULL,
Name VARCHAR(500) NOT NULL,
CONSTRAINT PK_AtomEntity PRIMARY KEY NONCLUSTERED (Id),
);
CREATE TABLE RootEntity_Children
(
ParentId UNIQUEIDENTIFIER NOT NULL,
OrderIndex INT NOT NULL,
ChildContainerEntityId UNIQUEIDENTIFIER NULL,
ChildAtomEntityId UNIQUEIDENTIFIER NULL,
ChildIsContainerEntity BIT NOT NULL,
CONSTRAINT PK_RootEntity_Children
PRIMARY KEY NONCLUSTERED (ParentId, OrderIndex),
-- foreign key to parent RootEntity
CONSTRAINT FK_RootEntiry_Children__RootEntity
FOREIGN KEY (ParentId) REFERENCES RootEntity (Id)
ON DELETE CASCADE,
-- foreign key to referenced (child) ContainerEntity
CONSTRAINT FK_RootEntiry_Children__ContainerEntity
FOREIGN KEY (ChildContainerEntityId) REFERENCES ContainerEntity (Id)
ON DELETE CASCADE,
-- foreign key to referenced (child) AtomEntity
CONSTRAINT FK_RootEntiry_Children__AtomEntity
FOREIGN KEY (ChildAtomEntityId) REFERENCES AtomEntity (Id)
ON DELETE CASCADE,
);
CREATE TABLE ContainerEntity_Children
(
ParentId UNIQUEIDENTIFIER NOT NULL,
OrderIndex INT NOT NULL,
ChildContainerEntityId UNIQUEIDENTIFIER NULL,
ChildAtomEntityId UNIQUEIDENTIFIER NULL,
ChildIsContainerEntity BIT NOT NULL,
CONSTRAINT PK_ContainerEntity_Children
PRIMARY KEY NONCLUSTERED (ParentId, OrderIndex),
-- foreign key to parent ContainerEntity
CONSTRAINT FK_ContainerEntity_Children__RootEntity
FOREIGN KEY (ParentId) REFERENCES ContainerEntity (Id)
ON DELETE CASCADE,
-- foreign key to referenced (child) ContainerEntity
CONSTRAINT FK_ContainerEntity_Children__ContainerEntity
FOREIGN KEY (ChildContainerEntityId) REFERENCES ContainerEntity (Id)
ON DELETE CASCADE,
-- foreign key to referenced (child) AtomEntity
CONSTRAINT FK_ContainerEntity_Children__AtomEntity
FOREIGN KEY (ChildAtomEntityId) REFERENCES AtomEntity (Id)
ON DELETE CASCADE,
);
CREATE TRIGGER Delete_RootEntity_Children ON RootEntity_Children FOR DELETE
AS
DELETE FROM ContainerEntity WHERE Id IN (SELECT ChildContainerEntityId FROM deleted)
DELETE FROM AtomEntity WHERE Id IN (SELECT ChildAtomEntityId FROM deleted)
GO
CREATE TRIGGER Delete_ContainerEntiy_Children ON ContainerEntity_Children FOR DELETE
AS
DELETE FROM ContainerEntity WHERE Id IN (SELECT ChildContainerEntityId FROM deleted)
DELETE FROM AtomEntity WHERE Id IN (SELECT ChildAtomEntityId FROM deleted)
GO
答案 0 :(得分:1)
尝试没有触发器:
Entity
Id
Name
PRIMARY KEY (id)
ParentEntity --- Root or Container
Id
PRIMARY KEY (id)
FOREIGN KEY (Id) REFERENCES Entity (Id)
ON DELETE CASCADE
ChildEntity --- Container or Atom
Id
ParentId
OrderIndex
PRIMARY KEY (Id)
UNIQUE KEY (ParentId, OrderIndex)
FOREIGN KEY (Id) REFERENCES Entity (Id)
ON DELETE CASCADE
FOREIGN KEY (ParentId) REFERENCES ParentEntity (Id)
ON DELETE CASCADE
其余的:
RootEntity
Id
PRIMARY KEY (Id)
FOREIGN KEY (Id) REFERENCES ParentEntity (Id) --- it is a Parent
ON DELETE CASCADE
ContainerEntity
Id
PRIMARY KEY (Id)
FOREIGN KEY (Id) REFERENCES ParentEntity (Id) --- it is a Parent
ON DELETE CASCADE
FOREIGN KEY (Id) REFERENCES ChildEntity (Id) --- and a Child
ON DELETE CASCADE
AtomEntity
Id
PRIMARY KEY (Id)
FOREIGN KEY (Id) REFERENCES ChildEntity (Id) --- it is a Child
ON DELETE CASCADE