SQL Server 2008 - 如何使用DELETE触发器更新字段

SQL Server 2008 - 如何使用DELETE触发器更新字段

问题描述:

我想更新记录正在从中删除的同一个表中的字段,但不太确定如何。该表是非常简单,上有一个自我参考: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

请注意,如果您用适当的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 

对不起,得到了错误的问题在第一时间......在这种情况下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

您可以使用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