级联删除通过触发器

时间:2015-10-14 18:19:06

标签: sql-server sql-server-2012

我有:

  1. 表"项目"使用PK ID

  2. 一张桌子"区域"使用PK ID和FK ProjectID

  3. 一张桌子" Cals"使用PK ID和FK ZoneID

  4. 触发:

    ALTER TRIGGER [dbo]。[DeleteProject] ON [dbo]。[项目]  INSTEAD OF DELETE   如   DECLARE @ProjectID int   SELECT @ProjectID = deleted.ID FROM deleted

    DELETE Zones WHERE ProjectID = @ProjectID

    删除项目      从DELETED D      INNER JOIN项目T ON T.ID = D.ID

  5. 触发:

    ALTER TRIGGER [dbo]。[DeleteZone] ON [dbo]。[Zones]  INSTEAD OF DELETE   如   DECLARE @ZoneID int   SELECT @ZoneID = deleted.ID FROM deleted

    DELETE Cals WHERE ZoneID = @ZoneID

    删除[区域]      从DELETED D      INNER JOIN [Zones] T ON T.ID = D.ID

  6. 通常它工作正常,但我收到错误

      

    {" DELETE语句与REFERENCE约束冲突   \" FK_Cals_Zones \&#34 ;.冲突发生在数据库\" PlasmaAir \"中,   table \" dbo.Cals \",column' ZoneID'。\ r \ n声明已被删除   终止"}

    当 1.区域有相同ProjectID的2条记录 2. Calc至少有一条ZoneID来自#1的记录

    为什么会发生以及如何解决?

1 个答案:

答案 0 :(得分:2)

我的猜测是你的删除有多个记录。您的触发器仅从CALS中删除第一个触发器,但所有这些触发器都来自区域,其中一些仍在CALS中。

假设您删除项目时它有三个区域记录。您的第一个触发器代码尝试删除所有那些但是命中而不是触发器。此选项仅选择要从CAL中删除的其中一条记录。然后它尝试删除已删除表中的所有内容(三个记录而不是一个),其中一个或多个记录在CAL中,因此您点击FK约束并且删除失败。

您需要完全设置两个触发器,并删除对从已删除表中提取数据的任何标量变量的所有引用。它们不属于SQL服务器中的触发器。