2012-02-18 3 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 

Так что, если я удалю Джейн (UserID = 2), я хотел бы триггер для обновления любая запись с EmailUserID из 2. Как я могу это сделать?

+0

Вы знаете, что это будет работать только в том случае, если вы * не * имеете свой собственный внешний ключ, верно? Это означает, что вы можете использовать любую ценность в EmailUserID, и SQL Server не собирается жаловаться. –

ответ

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 

Sample попытаться создать копию 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

К сожалению, есть вопрос неправильно в первый раз ... после запуска можно в этом случае:

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, если вы не хотите вводить WHERE EmailUserID IN (SELECT UserID FROM DELETED). – Robert

+0

@Robert: Вы хотите обновить таблицу пользователя и установить столбец EmailUserID равным null, если строка была затронута исходной инструкцией удаления, правильно? Предполагая, что UserID является PK таблицы, триггер устанавливает EmailUserID равным null во всех строках, которые должны были быть удалены исходной инструкцией delete. – Mithrandir

+0

Я также сделал исправление здесь. Вы обновляли строку, в которой совпадали идентификаторы пользователей. Я согласен с тем, что вам нужно более внимательно рассмотреть вопрос. –

7

Вы можете использовать ПОСЛЕ УДАЛЕНИЕ Trigger:

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

Я сделал две поправки. Нет идентификационной колонки; исправил его как UserID. Также квалифицируется соединение, потому что EmailUserID существует в обоих Пользователях и удаляется - это должно привести к сбою анализа из-за неоднозначного имени столбца. –

+0

@AaronBertrand Thanx много. –

+0

@ OlegDok: Очень жаль, я ошибся не так. – Mithrandir

Смежные вопросы