我想在一个表中插入值后更新多个表和值,因此我创建了一个触发器。它适用于一行插入,但是一旦插入更多行,SQL Server就会出现以下错误:
子查询返回的值超过1。当子查询跟随=或子查询用作表达式时,不允许这样做?
这是我的触发器:
CREATE TRIGGER [dbo].[tbl_Sales_ForInsert]
ON [dbo].[SALES]
FOR INSERT
AS
BEGIN
DECLARE @ITEMMODEL varchar(100)
SELECT @ITEMMODEL = ITEM_MODEL FROM inserted
UPDATE SALES
SET PROFIT = TOTAL_PRICE - (SELECT QUANTITY FROM SALES WHERE ITEM_MODEL = @ITEMMODEL) * (SELECT RATE FROM ITEM_DETAILS WHERE ITEM_MODEL = @ITEMMODEL)
WHERE ITEM_MODEL = @ITEMMODEL
UPDATE ITEM_DETAILS
SET QUANTITY = QUANTITY - (SELECT QUANTITY FROM SALES WHERE ITEM_MODEL = @ITEMMODEL)
WHERE ITEM_MODEL = @ITEMMODEL
--UPDATE ITEM_DETAILS SET AMOUNT = AMOUNT - (SELECT RATE FROM ITEM_DETAILS WHERE ITEM_MODEL=@ITEMMODEL) * (SELECT QUANTITY FROM SALES WHERE ITEM_MODEL=@ITEMMODEL) where ITEM_MODEL=@ITEMMODEL
END
当我第一次在SALES
表中插入数据时,更新成功但是第二次它给出了上面的错误,记住ITEM_MODEL
是SALES表中的外键约束。
我一直在遭受这个错误,任何人都可以帮助我吗?
答案 0 :(得分:8)
您的根本缺陷是,您似乎希望触发器每行一次 - 这在SQL Server中是 NOT 。相反,触发器会在每个语句时触发,而伪表Inserted
可能包含多行。
鉴于该表可能包含多行 - 您希望在这里选择哪一行?
SELECT @ITEMMODEL = ITEM_MODEL FROM inserted
未定义 - 您可以从Inserted
中的任意行获取值。
您需要使用Inserted
WILL 包含多行的知识重写整个触发器!您需要使用基于集合的操作 - 不要只期望Inserted
中的一行!
因此,在您的情况下,您的触发器代码应如下所示:
CREATE TRIGGER [dbo].[tbl_Sales_ForInsert]
ON [dbo].[SALES]
FOR INSERT
AS
BEGIN
-- update the dbo.Sales table, set "PROFIT" to the difference of
-- TOTAL_PRICE and (QUANTITY * RATE) from the "Inserted" pseudo table
UPDATE s
SET s.PROFIT = i.TOTAL_PRICE - (i.QUANTITY * i.RATE)
FROM dbo.Sales s
INNER JOIN Inserted i ON i.ITEM_MODEL = s.ITEM_MODEL
-- update the dbo.ITEM_DETAILS table
UPDATE id
SET id.QUANTITY = id.QUANTITY - i.Quantity
FROM dbo.ITEM_DETAILS id
INNER JOIN Inserted i ON id.ITEM_MODEL = i.ITEM_MODEL
END
答案 1 :(得分:0)
Marc_s是正确的,期望插入的伪表包含多行。如果子查询仅限于具有TOP(1)的一行,则存在查询可能有效的情况。
UPDATE SALES
SET PROFIT = TOTAL_PRICE - (SELECT TOP(1) QUANTITY FROM SALES WHERE ITEM_MODEL = @ITEMMODEL)
* (SELECT TOP(1) RATE FROM ITEM_DETAILS WHERE ITEM_MODEL = @ITEMMODEL)
WHERE ITEM_MODEL = @ITEMMODEL