【问题标题】:MS SQL "ON DELETE CASCADE" multiple foreign keys pointing to the same table?MS SQL“ON DELETE CASCADE”多个外键指向同一个表?
【发布时间】:2021-10-25 12:33:41
【问题描述】:

我有一个问题,我需要对指向同一个表的多个外键进行级联..

[Insights]
| ID | Title        |
| 1  | Monty Python |
| 2  | Spamalot     | 

[BroaderInsights_Insights]
| broaderinsight_id | insight_id |
| 1                 | 2          |

基本上,当洞察表中的记录一或二被删除时,我也需要删除关系..

我试过了:

 CREATE TABLE broader_insights_insights(id INT NOT NULL IDENTITY(1,1),
   broader_insight_id INT NOT NULL REFERENCES insights(id) ON DELETE CASCADE,
   insight_id INT NOT NULL REFERENCES insights(id) ON DELETE CASCADE,
   PRIMARY KEY(id))
Go

这会导致警告说级联“可能导致循环或 多级联路径"

所以我尝试将级联添加到insight_id,结果是:

DELETE 语句与 REFERENCE 约束冲突

有什么想法吗?

谢谢

丹尼尔

【问题讨论】:

  • 这样的级联删除很少是一个好主意。想想如果你也有“布赖恩的生活”会发生什么。删除 LoB,删除级联以杀死 Monty Python,后者级联删除 Spamalot。由于是循环关系,删除圈子的任何成员都会删除整个圈子。
  • 我误解了级联吗?我认为这个概念是当引用的记录被删除时,关系也被删除了?您建议如何实现这一目标?
  • 您需要在一个事务中进行删除(在存储过程中最简单),而不是通过级联删除。
  • @Marc B - 级联只在一个方向上工作。删除 LoB 会删除此链接表中对 LoB 的任何引用,但不会影响 Insights 中的任何其他行。
  • 对多个级联路径的需求无处不在,而且完全合法。几乎任何时候你有一个多对多的关系,你都需要它。假设您有 Parts、Vendors 和 PartVendors。如果您删除一个部件,您希望删除该部件的 PartVendors 中的任何行。如果您删除一个供应商,您希望删除该供应商的 PartVendors 中的任何行。但 SQL Server 不支持这一点。太烦人了,没有其他严重的数据库引擎有这个问题,人们在 2005 年抱怨它,Microsfot 在 2008 年同意这是一个“理想的功能”,但在 2014 年他们仍然没有它。

标签: sql sql-server foreign-keys constraints cascading-deletes


【解决方案1】:

您必须将此作为 INSTEAD OF 删除触发器来实现洞察力,才能使其发挥作用。比如:

create trigger T_Insights_D
on Insights
instead of delete
as
    set nocount on
    delete from broader_insights_insights
    where insight_id in (select ID from deleted) or
    broader_insight_id in (select ID from deleted)

    delete from Insights where ID in (select ID from deleted)

经常使用级联删除和大量外键,您需要花时间制定“级联”顺序,以便在“树”顶部发生的删除成功级联到引用表。但在这种情况下这是不可能的。

【讨论】:

    猜你喜欢
    • 2019-10-06
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多