删除触发器上的SQL Server无法达到我的期望

时间:2018-11-26 11:29:18

标签: sql-server triggers database-trigger

删除菜碟时,触发器应触发。所有包含这道菜的订单都将被删除。

到目前为止,我已经有了这个脚本:

create trigger OnDishDeleted 
on Dish 
after delete as 
begin 
    delete from Dish_Order 
    where Dish_ID = (select Dish_ID from deleted) 
end

当我尝试删除碟子时,出现错误:

  

DELETE语句与REFERENCE约束“ FK_Dish_Order_Dish”冲突。在数据库“ davay_rabotai2”的表“ dbo.Dish_Order”的“ Dish_ID”列中发生了冲突。

ER图:

Click!

1 个答案:

答案 0 :(得分:0)

如果您需要先删除另一个表中的行,请使用instead of触发器。
这是一个可以帮助您入门的示例。

CREATE trigger OnDishDeleted on dbo.Dish
instead of delete 
as
begin
     set nocount on

     delete from Dish_Order where Dish_ID in (select Dish_ID from deleted) 
     delete from Dish where Dish_ID in (select Dish_ID from deleted) 
end

与常规触发器的区别在于,您还需要在此触发器中自行从表Dish中删除行。
instead of触发器不会删除任何内容,只会在给出delete语句时触发,您必须自己完成所有工作。

更多信息
https://docs.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql?view=sql-server-2017

https://msdn.microsoft.com/en-us/library/def01zh2.aspx

还要注意,我在where子句中使用IN而不是=,这是因为触发器中的deleted可以有多行。那是触发代码中的另一个缺陷。始终假定触发器中可以有多于一行。

也就是说,您的解决方案还有另一个问题。
从您的ER图中,我还看到您还具有付款和其他行,这些行和其他行存储在与盘子链接的其他表格中。您还需要删除这些行。
但是删除付款并不是我希望在数据库中看到的事情。
确定要执行此操作吗?