删除触发器在执行时不起作用

时间:2015-06-11 14:50:34

标签: sql-server triggers

在删除table1中的一行后,是否有可能从table2(具有table1的引用)中删除? (例如:如果我同时从客户删除CustomerID以删除他所做的订单(OrderID))

CREATE TRIGGER DelBilete
ON Curse 
AFTER DELETE
AS 
BEGIN
  DELETE FROM Bilete 
  WHERE IDCursa IN (SELECT IDCursa FROM Curse)
END

1 个答案:

答案 0 :(得分:2)

有两种方法可以执行此操作:使用级联删除(使用外键约束设置):

ALTER TABLE [dbo].[Orders]  WITH NOCHECK ADD  CONSTRAINT    
[FK_Orders_Customer] FOREIGN KEY([customerId])
REFERENCES [dbo].[Customer] ([customerId])
ON DELETE CASCADE

...或者使用触发器,正如您所尝试的那样。 (你可能会尝试这样的事情。实际上。免责声明:这是来自记忆而未经过测试。)

CREATE TRIGGER DelBilete
ON Curse 
AFTER DELETE
AS 
BEGIN
  DELETE FROM Bilete WHERE IDCursa IN(SELECT IDCursa FROM deleted)
END
GO

如果您只是删除主键表中存在外键的位置,您将删除所有订单(或Bilete包含的任何订单)!

ETA:获取外键约束错误时:

  

delete语句与引用约束冲突   “FK_Bilete_Curse”。

如果您有外键约束,并且想要从主表(Curse)中删除并从相关表(Bilete)中删除相关记录,则{{1}触发器无法解决问题,正是因为它是一个AFTER触发器。它在记录被删除后发生。如果无法删除它们,则触发器不会触发。如果这些记录被其他记录引用,则无法删除它们。

所以你有两个选择:

  1. 上面的级联删除;

  2. AFTER。 (有关详细信息,请参阅here。)

  3. 你的案例中的INSTEAD OF触发器看起来像这样(再次,从内存和文档,未经测试):

    INSTEAD OF trigger

    使用CREATE TRIGGER DelBilete ON Curse INSTEAD OF DELETE AS BEGIN DELETE FROM Bilete WHERE IDCursa IN(SELECT IDCursa FROM deleted) DELETE FROM Curse WHERE IDCursa IN (SELECT IDCursa from deleted) END GO 触发器,当您执行代码以从INSTEAD OF删除记录时,触发器会运行。它从Curse删除相关记录,然后从Bilete执行删除。

    Curse触发器不会递归运行,因此触发器中INSTEAD OF的DELETE不会强制执行另一次触发器运行。