Sql server MSSQL:如何有多个引用同一个表的级联

Sql server MSSQL:如何有多个引用同一个表的级联,sql-server,database-trigger,cascading-deletes,Sql Server,Database Trigger,Cascading Deletes,可能情况很复杂,但这是我模型的简化版本: 情况: drop table table4 drop table table2 drop table table3 drop table table1 drop table table0 create table table0 ( id integer not null primary key ) create table table1 ( id integer not null primary key ) create table

可能情况很复杂,但这是我模型的简化版本:

情况:

drop table table4
drop table table2
drop table table3
drop table table1
drop table table0

create table table0 (
    id integer not null primary key
)

create table table1 (
    id integer not null primary key
)

create table table2 (
    id integer not null primary key,
    table0_id integer not null,
    table1_id integer not null
)

create table table3 (
    id integer not null primary key,
    table1_id integer not null
)

create table table4 (
    id integer not null primary key,
    table2_id integer not null,
    table3_id integer not null
)

alter table table2 add constraint fk_table2_table0 foreign key (table0_id)
references table0 (id) on delete cascade on update no action

alter table table2 add constraint fk_table2_table1 foreign key (table1_id)
references table1 (id) on delete cascade on update no action

alter table table3 add constraint fk_table3_table1 foreign key (table1_id)
references table1(id) on delete cascade on update no action

alter table table4 add constraint fk_table4_table2 foreign key (table2_id)
references table2(id) on delete cascade on update no action

alter table table4 add constraint fk_table4_table3 foreign key (table3_id)
references table3(id) on delete no action on update no action

GO
CREATE TRIGGER WhenRowFromTable3IsDeleted ON table3
    FOR DELETE       
AS
BEGIN
    DELETE FROM table4 WHERE table3_id = (SELECT id FROM DELETED)
END
GO

INSERT INTO table0 (id) VALUES (1)
INSERT INTO table1 (id) VALUES (1)
INSERT INTO table2 (id, table0_id, table1_id) VALUES (1, 1, 1)
INSERT INTO table3 (id, table1_id) VALUES (1, 1)
INSERT INTO table4 (id, table2_id, table3_id) VALUES (1,1,1)

DELETE FROM table3 WHERE id = 1

SELECT * FROM table1, table0
结果:
DELETE语句与引用约束“fk_table4_table3”冲突。冲突发生在数据库“testing”、表“dbo.table4”、列“table3\u id”中。

问题

如何从
表3
中删除记录?正如您所看到的,我已经用触发器
尝试了删除
,但这会导致FK约束错误(因此删除的
实际上是删除后的
)。

我也尝试过使用
而不是DELETE
,但这无法使用,因为父级(
table2
)也有一个ON-DELETE级联。

MSSQL不支持多路径级联删除


其他数据库管理系统(如PostgreSQL)也支持它。

通过创建一个触发器,首先删除子级表记录,然后在使用instead而不是delete之后再删除它本身,您可以触发子触发器,就像按正确顺序执行的级联模式一样

这通过添加更多的逻辑来解决级联问题。此外,您可能希望在较大的键上使用主键而不是此处的ID来选择正确的记录

drop table table4

drop table table2

drop table table3

drop table table1

drop table table0



create table table0 (

   id integer not null primary key

)



create table table1 (

   id integer not null primary key

)



create table table2 (

   id integer not null primary key,

   table0_id integer not null,

   table1_id integer not null

)



create table table3 (

   id integer not null primary key,

   table1_id integer not null

)



create table table4 (

   id integer not null primary key,

   table2_id integer not null,

   table3_id integer not null

)



alter table table2 add constraint fk_table2_table0 foreign key (table0_id)

references table0 (id) on delete cascade on update no action



alter table table2 add constraint fk_table2_table1 foreign key (table1_id)

references table1 (id) on delete cascade on update no action



alter table table3 add constraint fk_table3_table1 foreign key (table1_id)

references table1(id) on delete no action on update no action



alter table table4 add constraint fk_table4_table2 foreign key (table2_id)

references table2(id) on delete cascade on update no action



alter table table4 add constraint fk_table4_table3 foreign key (table3_id)

references table3(id) on delete no action on update no action



GO

CREATE TRIGGER WhenRowFromTable3IsDeleted ON table3

   INSTEAD OF DELETE      

AS

BEGIN

   DELETE FROM table4 WHERE table3_id = (SELECT id FROM DELETED)

    DELETE FROM table3 WHERE id = (SELECT id FROM DELETED)

END

GO

CREATE TRIGGER WhenRowFromTable1IsDeleted ON table1

   INSTEAD OF DELETE      

AS

BEGIN

   DELETE FROM table3 WHERE table1_id = (SELECT id FROM DELETED)

    DELETE FROM table1 WHERE id = (SELECT id FROM DELETED)

END

GO



INSERT INTO table0 (id) VALUES (1)

INSERT INTO table1 (id) VALUES (1)

INSERT INTO table2 (id, table0_id, table1_id) VALUES (1, 1, 1)

INSERT INTO table3 (id, table1_id) VALUES (1, 1)

INSERT INTO table4 (id, table2_id, table3_id) VALUES (1,1,1)



DELETE FROM table3 WHERE id = 1



SELECT * FROM table1, table0

SQL Server没有“删除时自动删除外键约束”功能。如果要删除外键引用的表,则需要先删除这些约束。我非常建议,这个“功能”是设计出来的。我(个人)不希望我的同事在不付出努力的情况下删除约束引用的表,好像他们确实需要删除他们需要的表以了解其含义(他们可能会立即寻求帮助并很快被阻止)。删除表和“记录”(行)完全不同,好吧。所以我的问题不够清楚。。。我改了。并将删除我的评论。感谢这里的问题,如果你的关系。无法在
fk_table4\u table3
上启用级联,因为它可能会导致级联循环(这是不允许的)。我怀疑设计可能是“有缺陷的”,如果它有一个像上面这样的关系,然而,这将是不可能告诉我们的简化版本,我恐怕。目前,您必须先删除
表4
中的行,然后才能转到
表3
。谢谢。这个数据库是用MySQL设计的,MySQL处理它时,删除级联上的所有FK都没有任何问题。因为应用程序必须同时支持这两个数据库。你有什么建议?在
表3
表4
之间添加一个表?我知道这一点。但不幸的是,这并没有回答我的问题,也没有解决我的问题。迁移到其他数据库不是解决方案。我改变了原来的帖子,让它更清楚。提前谢谢这看起来是个解决办法。不是完美的程序,但我似乎工作!