【问题标题】:SQL trigger to delete from another table从另一个表中删除的 SQL 触发器
【发布时间】:2017-07-26 09:52:06
【问题描述】:

我有两张桌子:

产品

Product ID | Quantity

OrdersLines

Product ID | Amount --(multiple lines with the same ID)

当然,在我从Products 表中删除产品之前,我需要先从OrdersLines 表中删除所有具有该产品ID 的订单行。

所以我写了一个触发器来做到这一点:

CREATE TRIGGER [dbo].[atbl_Sales_Products_DTrig]
ON [dbo].[atbl_Sales_Products]
FOR DELETE
AS
BEGIN
    DELETE FROM atbl_sales_OrdersLines
    WHERE ProductID = (SELECT ProductID FROM deleted)
END

但是,当我尝试从 Products 表中删除表单时,它仍然显示:

相关表 (Sales OrdersLines) 中的某些行必须先删除才能删除此行

我在这里做错了什么?

按要求编辑:主要约束:

[dbo].[atbl_Sales_OrdersLines]  WITH CHECK ADD  CONSTRAINT 
[FK_atbl_Sales_OrdersLines_atbl_Sales_Products] FOREIGN KEY([ProductID])
REFERENCES [dbo].[atbl_Sales_Products] ([ProductID])

【问题讨论】:

  • 您是否有不想使用cascading delete 的原因?
  • 是的,我知道这可以解决问题。但是,我这样做是为了分配。它需要在触发器中解决。
  • 触发器(称为AFTER触发器)在表中删除操作后执行,因此出现错误信息。您需要的是一个INSTEAD OF 触发器,要正确处理它们有点棘手。阅读全文:docs.microsoft.com/en-us/sql/relational-databases/triggers/…

标签: sql-server tsql


【解决方案1】:

这种情况下的主要问题是触发器被创建为FOR DELETE 触发器。所以它在删除操作后被触发 - 这会导致错误。

您应该将其创建为INSTEAD OF DELETE 触发器,它将解决此问题。

第二个问题是你不应该在子查询中使用=,因为它可以返回多于一行。您应该使用IN 运算符。

您可以在下面看到导致这两个问题出现错误的示例。

INSERT INTO Products(ProductId, Quantity)
SELECT 1,1
UNION
SELECT 2,2
GO

INSERT INTO OrdersLines(ProductId,Amount)
SELECT 1,2
UNION
SELECT 1,3
UNION
SELECT 2,4
UNION
SELECT 2,5
GO

DELETE Products
GO

当触发器正常时,这将通过。

【讨论】:

  • 谢谢,这解决了我的问题。只是一点点评论,我还需要编写一个额外的查询来从产品表中删除。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-30
  • 2015-09-30
  • 1970-01-01
  • 1970-01-01
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多