从 SQL 中的多个表中级联删除行

Posted

技术标签:

【中文标题】从 SQL 中的多个表中级联删除行【英文标题】:Cascade delete rows from multiple tables in SQL 【发布时间】:2021-11-06 13:58:42 【问题描述】:

我有 3 个这样的表:

表 1:ID、名称 表 2:ID、名称 表 3:Id、EntityName (nvarchar)、EntityId (int)

Table3 上没有外键。我将 Table1 和 Table2 的行插入到 Table3 中,如下所示:

Id EntityName EntityId OtherColumn(s)
1 Table1 1 ...
2 Table2 1 ...
3 Table2 2 ...

当我从 Table1 或 Table2 中删除一行时,如何将它从 Table3 中级联?

【问题讨论】:

这能回答你的问题吗? SQL Server ON DELETE Trigger 只需使用触发器而不是任何地方的任何级联。 【参考方案1】:

您可以在每个表上创建一个delete trigger,以从table3中删除匹配的行,例如:

create trigger Table1Delete on dbo.table1
for delete 
as
if @@RowCount = 0 return
set nocount on

delete from t3
from deleted d
join table3 t3 on t3.EntityName='Table1' and d.Id=t3.EntityId

Table2 也有类似的

【讨论】:

我太专注于级联删除,我完全忘记了触发器。 旁白:我会使用not exists ( select 42 from deleted ),而不是@@RowCount = 0。它避免了由于在检查之前插入语句或由于merge 语句而触发触发器而可能导致的任何混淆。 Using @@rowcount 来自文档和微软推荐的内容;尽管在以后的版本中不再是这种情况,但在旧版本中访问插入/删除的表是一项代价高昂的操作,需要尽量减少。【参考方案2】:

这就是您可以编写查询以“模仿”级联删除的方式:

delete from table2 t2
where exists(select 1 from table3
             where t2.id = entityId and EntityName = 'Table2')

delete from table1 t1
where exists(select 1 from table3
             where t1.id = entityId and EntityName = 'Table1')

如果您有从 table3 中删除的某些条件,您还应该在这些查询中包含它。

更新

要自动执行此操作,您需要使用级联删除操作定义外键。但是只能在列上定义一个外键,因此您需要有两列——一列用于引用table1,第二列用于引用table2。然后你需要定义级联删除。

使用当前设计(一列引用多个表)这是不可能的,您需要解决(建议在表上实现删除触发器)。

【讨论】:

我写这些查询没有问题。我问有没有办法用外键做到这一点。 @YSFKBDY 查看更新。 我有两个引用:EntityName 和 EntityId。

以上是关于从 SQL 中的多个表中级联删除行的主要内容,如果未能解决你的问题,请参考以下文章

sql中级联删除,级联更新是怎么理解的?

如何理解access设置中的“级联更新”和“级联删除”?

多表联查时的sql删除语句的写法,即级联删除,将相关联的数据级联删除

SQL 怎么级联删除语句

SQL 怎么级联删除语句

如何在 SQL Server 中使用级联删除?