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的任何记录。我该如何完成此操作?
请注意,如果您用适当的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
你能简单地解释一下吗?通过看起来,这将更新用户表的UserID是DELETE用户ID,除非你打算把WHERE EmailUserID IN(SELECT用户ID FROM DELETED)。 – Robert 2012-02-18 16:19:19
@Robert:如果行受到原始删除语句的影响,您想要更新用户表并将列EmailUserID设置为null,对吧?假设UserID是表的PK,则触发器将在所有行中将EmailUserID设置为null,这些行将被原始删除语句删除。 – Mithrandir 2012-02-18 16:24:33
我也在这里做了一个修正。您正在更新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
我做了两个更正。没有ID列;将其更正为UserID。由于EmailUserID存在于两个用户中并且被删除,所以也限定了联接,由于列名不明确,这会导致解析失败。 – 2012-02-18 16:42:53
@AaronBertrand非常感谢。 – 2012-02-18 16:45:20
@OlegDok:真的很抱歉,我错了。 – Mithrandir 2012-02-18 16:51:26
你知道这只会在你不*有自引用外键的时候才有效,对吗?这意味着你可以在EmailUserID中填充任何值,并且SQL Server不会抱怨。 – 2012-02-18 16:45:02