我有一个触发器,当在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
答案 0 :(得分:3)
您是否考虑过固定扳机?假设已删除的行是ONE行-可能不是,则此插入是可恶的,并且逐行删除行只会使问题隐藏起来,直到弹出为止。
正确的方法是:
摆脱所有变量。他们没有道理。
使用Inser INTO .... SELCT语法选择已删除的数据,并将其插入到发票明细历史记录表中。基本上,这将需要使用已删除的表作为源(在insert into的选择部分中)。
这也将大大提高速度-您可以使用bascailyl一次(一组)运行许多冗余操作,而不使用SQL。即使您的代码不会损坏(一行),也可以一次选择所有SET。您可以选择多个变量,然后一次选择多个变量。
但是实际上,在您的情况下,变量没有任何意义。您可以通过从已删除表中选择数据来直接插入历史表。
答案 1 :(得分:2)
您显然还在学习,所以让我举一个@tomtom所指的例子...
ALTER trigger [dbo].[deleteinvoicedetails]
on [dbo].[InvoiceDetails]
AFTER DELETE
AS
BEGIN
INSERT INTO
InvoiceDetailsHistory
SELECT
InvoiceID,
FoodID,
Quantity,
UnitPrice,
Totalprice
FROM
deleted
END
无论删除多少行,此方法都有效。