子查询返回的值超过1.当子查询跟随=或子查询用作表达式时,这是不允许的?

use*_*450 3 t-sql sql-server triggers

我想在一个表中插入值后更新多个表和值,因此我创建了一个触发器.它适用于一行插入,但是一旦插入更多行,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
Run Code Online (Sandbox Code Playgroud)

当我SALES第一次在表中插入数据时,更新成功但是第二次它给出了我上面的错误记住ITEM_MODEL是SALES表中的外键约束.

我一直在遭受这个错误,任何人都可以帮助我吗?

mar*_*c_s 8

你的根本缺陷是你似乎希望每行触发一次触发器- 这不是 SQL Server中的情况.相反,触发器每个语句触发一次,伪表Inserted可能包含多行.

鉴于该表可能包含多行 - 您希望在这里选择哪一行?

SELECT @ITEMMODEL = ITEM_MODEL FROM inserted
Run Code Online (Sandbox Code Playgroud)

它是未定义的 - 您可以从中获取任意行的值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
Run Code Online (Sandbox Code Playgroud)

  • 我无法形容我有多欣赏你的回答。我在 SQL Server 上工作了很多年,并且认为没有办法在具有触发器的表中进行多次更新。但是您展示了 Insert 可以有多行,并且 SQL Server 可以使用触发器对表进行多次插入和更新。非常感谢你!! (2认同)