Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server 2008-如何使用删除触发器更新字段_Sql_Sql Server 2008 - Fatal编程技术网

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

SQL Server 2008-如何使用删除触发器更新字段,sql,sql-server-2008,Sql,Sql Server 2008,我想更新同一个表中的一个字段,该表中的记录正在被删除,但不太确定如何更新。该表非常简单,上面有一个自引用: UserID FName EmailAddress EmailUserID 1 Frank frank@g.com 2 2 Jane jane@g.com NULL 3 John john@g.com 1 4 Brett brett@g.com 2 这是我的扳机: CREA

我想更新同一个表中的一个字段,该表中的记录正在被删除,但不太确定如何更新。该表非常简单,上面有一个自引用:

UserID    FName   EmailAddress  EmailUserID
1         Frank   frank@g.com   2
2         Jane    jane@g.com    NULL
3         John    john@g.com    1
4         Brett   brett@g.com   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

因此,如果我删除janeuserid=2,我希望触发器用EmailUserID为2更新任何记录。我怎样才能做到这一点

对不起,第一次问错了问题。。。在这种情况下,后触发是可能的:

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

您可以使用删除后触发器:

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

请注意,如果使用适当的外键约束设置表,after触发器将不会执行此任务。删除逻辑上发生在触发器中的操作之前,因此您将得到:

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
示例尝试在tempdb中创建dbo.Users的副本,如上所述,然后运行以下操作:

INSERT dbo.Users(UserID, FName, EmailAddress, EmailUserID) VALUES
(1,'Frank','frank@g.com',2   ),
(2,'Jane ','jane@g.com ',NULL),
(3,'John ','john@g.com ',1  ),
(4,'Brett','brett@g.com',2  );

SELECT * FROM dbo.Users;
GO

DELETE dbo.Users WHERE UserID = 2;
GO

SELECT * FROM dbo.Users;
GO

DROP TABLE dbo.Users;
GO

你能简单解释一下吗?从外观上看,这将更新UserID为DELETE UserID的用户表,除非您想将where EmailUserID放入SELECT UserID FROM DELETED中。@Robert:如果行受原始DELETE语句影响,您想更新用户表并将列EmailUserID设置为null,对吗?假设UserID是表的主键,触发器将所有行中的EmailUserID设置为null,这些行是由原始的delete语句删除的。您正在更新用户标识匹配的行。我同意@Oleg,你需要更仔细地研究这个问题。我已经做了两个更正。没有ID列;更正为UserID。还限定了加入,因为EmailUserID同时存在于用户和已删除用户中-由于列名称不明确,这应该无法解析。您知道,只有在没有自引用外键的情况下,这才有效,对吗?这意味着您可以在EmailUserID中填充任何值,SQL Server不会抱怨。