2012-02-18 64 views
5

我想更新記錄正在從中刪除的同一個表中的字段,但不太確定如何。該表是非常簡單,上有一個自我參考:SQL Server 2008 - 如何使用DELETE觸發器更新字段

UserID FName EmailAddress EmailUserID 
1   Frank [email protected] 2 
2   Jane [email protected] NULL 
3   John [email protected] 1 
4   Brett [email protected] 2 

這裏是我的觸發器:

CREATE TRIGGER [dbo].[CAT_DeleteUser] 
    ON Users 
    AFTER DELETE 
AS 
BEGIN 

    SET NOCOUNT ON; 

    UPDATE Users 
    SET EmailUserID = NULL 
    WHERE EmailUserID = ID_OF_DELETED_USER <-- don't know how to get this 

END 

所以,如果我刪簡(用戶ID = 2),我想觸發更新EmailUserID爲2的任何記錄。我該如何完成此操作?

+0

你知道這隻會在你不*有自引用外鍵的時候纔有效,對嗎?這意味着你可以在EmailUserID中填充任何值,並且SQL Server不會抱怨。 – 2012-02-18 16:45:02

回答

3

請注意,如果您用適當的FOREIGN KEY約束設置表,後觸發器不會完成這項工作。該DELETE邏輯發生在觸發的操作之前,所以你會得到:

Msg 547, Level 16, State 0, Line 2 
The DELETE statement conflicted with the SAME TABLE REFERENCE constraint ... 

所以,如果你想要的數據完整性,使任何人都無法東西垃圾到EMailUserID列,您可以使用INSTEAD OF觸發如下:

CREATE TABLE dbo.Users 
(
    UserID INT NOT NULL PRIMARY KEY, 
    FName NVARCHAR(32), 
    EmailAddress VARCHAR(320), 
    EmailUserID INT NULL FOREIGN KEY REFERENCES dbo.Users(UserID) 
); 
GO 

CREATE TRIGGER [dbo].[CAT_DeleteUser] 
ON dbo.Users 
INSTEAD OF DELETE 
AS 
BEGIN 
    SET NOCOUNT ON; 

    -- clean up references first 
    UPDATE u SET u.EmailUserID = NULL 
     FROM dbo.Users AS u 
     INNER JOIN deleted AS d 
     ON u.EmailUserID = d.UserID; 

    -- now delete the row 
    DELETE u 
    FROM dbo.Users AS u 
    INNER JOIN deleted AS d 
    ON u.UserID = d.UserID; 
END 
GO 

樣品嚐試創建dbo.Users副本,這樣,在tempdb,然後運行這個):

INSERT dbo.Users(UserID, FName, EmailAddress, EmailUserID) VALUES 
(1,'Frank','[email protected]',2 ), 
(2,'Jane ','[email protected] ',NULL), 
(3,'John ','[email protected] ',1 ), 
(4,'Brett','[email protected]',2 ); 

SELECT * FROM dbo.Users; 
GO 

DELETE dbo.Users WHERE UserID = 2; 
GO 

SELECT * FROM dbo.Users; 
GO 

DROP TABLE dbo.Users; 
GO 
2

對不起,得到了錯誤的問題在第一時間......在這種情況下AFTER觸發器是可能的:

CREATE TRIGGER [dbo].[CAT_DeleteUser] 
    ON Users 
    AFTER DELETE 
AS 
BEGIN 

    SET NOCOUNT ON; 

    UPDATE Users 
    SET EmailUserID = NULL 
    WHERE EmailUserID IN (SELECT UserID FROM DELETED) 

END 
+0

你能簡單地解釋一下嗎?通過看起來,這將更新用戶表的UserID是DELETE用戶ID,除非你打算把WHERE EmailUserID IN(SELECT用戶ID FROM DELETED)。 – Robert 2012-02-18 16:19:19

+0

@Robert:如果行受到原始刪除語句的影響,您想要更新用戶表並將列EmailUserID設置爲null,對吧?假設UserID是表的PK,則觸發器將在所有行中將EmailUserID設置爲null,這些行將被原始刪除語句刪除。 – Mithrandir 2012-02-18 16:24:33

+0

我也在這裏做了一個修正。您正在更新UserID匹配的行。我同意@Oleg,你需要更仔細地看待這個問題。 – 2012-02-18 16:44:03

7

您可以使用DELETE AFTER觸發器:

CREATE TRIGGER [dbo].[CAT_DeleteUser] ON Users 
    AFTER DELETE 
AS 
BEGIN 

    SET NOCOUNT ON; 

    UPDATE Users 
    SET EmailUserID = NULL 
    FROM Users 
    JOIN DELETED 
     ON Users.EmailUserID = Deleted.UserID 

END 
+0

我做了兩個更正。沒有ID列;將其更正爲UserID。由於EmailUserID存在於兩個用戶中並且被刪除,所以也限定了聯接,由於列名不明確,這會導致解析失敗。 – 2012-02-18 16:42:53

+0

@AaronBertrand非常感謝。 – 2012-02-18 16:45:20

+0

@OlegDok:真的很抱歉,我錯了。 – Mithrandir 2012-02-18 16:51:26