2014-02-23 49 views
3

我想在一個表中插入值後更新多個表和值,所以我創建了一個觸發器。它工作正常一行的插入,但只要我插入多個行,SQL Server的給了我以下錯誤:子查詢返回的值超過1。當子查詢遵循=或子查詢用作表達式時,這是不允許的?

subquery returned more than 1 value. this is not permitted when the subquery follows = or when the subquery is used as an expression?

這裏是我的觸發器:

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 [email protected]) * (SELECT QUANTITY FROM SALES WHERE [email protected]) where [email protected] 
END 

正如我在SALES表中插入數據第一次更新成功,但第二次它給了我上面的錯誤記住ITEM_MODEL是SALES表中的外鍵約束。

我一直在遭受這個錯誤任何人都可以幫助我嗎?

+0

是您的外鍵唯一嗎? – Hamidreza

回答

7

你根本缺陷是,你似乎期望觸發被解僱行一次 - 這是在SQL Server的情況。相反,觸發器會根據語句觸發一次,而僞表Inserted可能包含多行

鑑於該表可能包含多行 - 您期望在此處選擇哪一個?

SELECT @ITEMMODEL = ITEM_MODEL FROM inserted 

它是不確定的 - 你可以從任意行中Inserted得到的值。

您需要用知識重寫您的整個觸發器Inserted包含多行!您需要使用基於集合的操作 - 不要指望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

我無法描述我多麼感激你的答案。我與SQL Server工作了很多年,並且認爲沒有辦法在有觸發器的表中進行多次更新。但是你展示了Insert可以有多行,並且SQL Server可以在帶有觸發器的表上進行多次插入和更新。非常感謝你! – Vil

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 
相關問題