2013-11-26 25 views
0

如何處理多行到更新觸發器/如何修改我的實際觸發器以具有當前行爲?如果我只更新一行的偉大工程,但如果我在同時更新多個行我得到的錯誤:在sql觸發器更新中處理多行

Msg 512, Level 16, State 1, Procedure TriggerUpdateAdvert, Line 9
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.TriggerUpdateAdvert 
ON dbo.Advert FOR UPDATE 
AS 
    DECLARE @OldStatus INT; 
    DECLARE @NewStatus INT; 
    DECLARE @ID UNIQUEIDENTIFIER; 

    SET @ID=(SELECT I.ID_Advert FROM INSERTED I); 
    PRINT @ID 
    SET @OldStatus=(SELECT D.Status FROM DELETED D WHERE [email protected]); 
    SET @NewStatus=(SELECT I.Status FROM INSERTED I WHERE [email protected]); 


    IF(@[email protected]) 
    BEGIN 
    print @OldStatus 
    print @NewStatus 
     IF(@NewStatus=1 or @NewStatus=3) 
     BEGIN 
      UPDATE Advert SET Published_Date=GETDATE() WHERE [email protected] 
     END 
    END 


GO 

編輯:

我創建下一個代碼:

 UPDATE A 
     SET A.Published_Date=GETDATE() 
     FROM Advert A 
     INNER JOIN Inserted I ON A.ID_Advert=I.ID_Advert 
     INNER JOIN Deleted D ON D.ID_Advert=A.ID_Advert 
     WHERE I.Status!=D.Status AND (I.Status IN (1,3) AND D.Status NOT IN (1,3)) 

你有什麼想法嗎?

+1

你**的主要缺陷**是你承擔觸發器將被稱爲**每行一次** - 這是** **不!它將在每個語句**中調用一次**,並且'Inserted'僞表可以包含多行** - 所以在這種情況下 - 您在這裏選擇多行中的哪一行? 'SET @ ID =(SELECT I.ID_Advert FROM INSERTED I);'....你需要**重寫你的觸發器**來考慮多行,並適當地處理它們! –

回答

2

避免在觸發器中使用PRINT。

,並確定它是這樣的:

ALTER TRIGGER dbo.TriggerUpdateAdvert 
ON dbo.Advert FOR UPDATE 
AS 
    UPDATE Advert SET Published_Date=GETDATE() 
    WHERE ID_Advert IN (
    SELECT i.id 
    FROM inserted i 
    INNER JOIN deleted d 
    ON i.ID_Advert = d.ID_Advert 
    WHERE i.Status <> d.Status 
    AND i.Status IN (1,3) 
    ) 
END 
+0

謝謝!是的,你說得對,我不應該使用PRINT。 – POIR

1
UPDATE a SET Published_Date = CURRENT_TIMESTAMP 
    FROM dbo.Advert AS a 
    INNER JOIN inserted AS i ON a.ID_Advert = i.ID_Advert 
    INNER JOIN deleted AS d ON i.ID_Advert = d.ID_Advert 
    WHERE i.Status IN (1,3) AND d.Status <> i.Status; 
+0

謝謝!你的代碼與我的代碼非常相似(請參閱我的編輯部分) – POIR

+0

@Otix對不起,由於某種原因,我沒有看到編輯,我想我是坐在這個問題上,沒有注意到它進來。所以,你添加了編輯,這裏還有一個問題嗎?這不可能產生你最初報告的錯誤信息,所以你在這裏尋找什麼其他想法? –

+0

其實我正在尋找最快/最好的方法....如果這是唯一的方法就沒關係。我將使用這種方法 – POIR