如何逐行删除以使触发器不会引发错误

How to delete rows one by one so that the trigger doesn't throw an error

我有一个触发器,当在 InvoiceDetails 中删除一行时,该行将被复制到 InvoiceDetailsHistory。当我执行 sql“DELETE FROM InvoiceDetails”时,我收到一条错误消息:

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

我想是因为我要一次删除所有行。我该如何解决这个问题?这是我的触发器:

ALTER trigger [dbo].[deleteinvoicedetails]       
on [dbo].[InvoiceDetails]
AFTER DELETE 
AS
DECLARE @InvoiceID int,@FoodID int,@quantity int,@UnitPrice float,@totalprice float
BEGIN
SET @InvoiceID = (Select InvoiceID from deleted)
SET @FoodID = (Select FoodID from deleted)
SET @quantity = (Select quantity from deleted)
SET @UnitPrice = (Select UnitPrice from deleted)
SET @totalprice = (Select totalprice from deleted)
INSERT INTO InvoiceDetailsHistory VALUES (@InvoiceID,@FoodID,@quantity,@UnitPrice,@totalprice)
END

您是否考虑过修复触发器?这个插入是令人厌恶的,假设删除的是一行 - 它可能不是,并且一个接一个地删除 rrows 只会使问题隐藏起来,直到它弹出。

正确的方法是:

  • 去掉所有变量。他们没有意义。

  • 使用 Inser INTO .... SELCT 语法 select 删除的数据并将其插入到发票明细历史记录中 table。这基本上需要使用已删除的 table 作为源(在插入的 select 部分)。

这也会非常快 - 你 bascailyl 运行 大量冗余操作一个一个(设置)而不是使用 SQL。即使您的代码不会被破坏(一行),所有 SET 也可以在一个 select 中完成。您可以 select 插入变量,并同时对多个变量进行操作。

但实际上,在您的情况下,变量没有任何意义。您可以直接从删除的 table.

中选择数据插入历史 table

你显然还在学习,所以让我举个例子来说明@tomtom 指的是什么......

ALTER trigger [dbo].[deleteinvoicedetails]       
on [dbo].[InvoiceDetails]
AFTER DELETE 
AS
BEGIN
INSERT INTO
  InvoiceDetailsHistory
SELECT
  InvoiceID,
  FoodID, 
  Quantity,
  UnitPrice,
  Totalprice
FROM
  deleted
END

无论删除多少行,这都有效。