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表中的外键约束.
我一直在遭受这个错误,任何人都可以帮助我吗?
你的根本缺陷是你似乎希望每行触发一次触发器- 这不是 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)