Триггер удаления SQL Server для обновления нескольких столбцов в одной таблице - PullRequest
2 голосов
/ 23 июня 2010

У меня есть следующий триггер:

CREATE TRIGGER Users_Delete
   ON  Users 
   AFTER DELETE
AS 
BEGIN

    SET NOCOUNT ON;

    -- Patients
    UPDATE Patients SET ModifiedByID=NULL WHERE ModifiedByID=ID;
    UPDATE Patients SET CreatedByID=NULL WHERE CreatedByID=ID;
    UPDATE Patients SET DeletedByID=NULL WHERE DeletedByID=ID;

END

Мне было интересно, есть ли способ «объединить» эти три оператора UPDATE во что-то вроде следующего:

UPDATE Patients SET 
(ModifiedByID=NULL WHERE ModifiedByID=ID) OR 
(CreatedByID=NULL WHERE CreatedByID=ID) OR 
(DeletedByID=NULL WHERE DeletedByID=ID);

Мне бы очень хотелось иметь только одно заявление для повышения производительности.

Причина, по которой я использую триггер вместо ON DELETE для FOREIGN KEY, заключается в том, что я получаю ошибку, что наличие более одного ON DELETE вызывает следующую ошибку:

Введение ограничения FOREIGN KEY 'FK_Patients_Users_Deleted' в таблицу 'Patients' может вызвать циклы или несколько каскадных путей. Укажите УДАЛИТЬ НЕТ ДЕЙСТВИЙ или ОБНОВИТЬ НЕТ ДЕЙСТВИЯ или измените другие ограничения FOREIGN KEY.

РЕДАКТИРОВАТЬ: было бы хорошо иметь индексы для всех столбцов ModifiedByID, CreatedByID, DeletedByID? Удаление пользователя, конечно, будет редкостью, поэтому стоит ли добавлять индексы в 3 столбца?

Ответы [ 3 ]

2 голосов
/ 23 июня 2010

Относительно вашего исходного вопроса.

Не совсем. Я не могу придумать ничего лучше, чем

UPDATE Patients 
SET ModifiedByID= CASE WHEN ModifiedByID=ID THEN NULL ELSE ModifiedByID END,
CreatedByID= CASE WHEN CreatedByID=ID THEN NULL ELSE CreatedByID END,
DeletedByID= CASE WHEN DeletedByID=ID THEN NULL ELSE DeletedByID END
WHERE
ModifiedByID  IN (SELECT ID FROM DELETED)
OR 
CreatedByID  IN (SELECT ID FROM DELETED)
OR
DeletedByID  IN (SELECT ID FROM DELETED)

Обратите внимание, что это правильно обрабатывает удаление нескольких строк. Из того, что вы опубликовали, неясно, работает ли ваш текущий триггер.

1 голос
/ 23 июня 2010

Вы можете сделать это в одном утверждении, но это не обязательно лучше для производительности.

UPDATE
    Patients
SET
    ModifiedByID = CASE WHEN ModifiedID = ID THEN NULL ELSE ModifiedID,
    CreatedByID = CASE WHEN CreatedByID = ID THEN NULL ELSE CreatedByID,
    DeletedByID = CASE WHEN DeletedByID = ID THEN NULL ELSE DeletedByID

Я действительно сомневаюсь, что это будет работать лучше, хотя.

1 голос
/ 23 июня 2010

Как то так?

UPDATE Patients SET 
ModifiedByID = CASE WHEN ModifiedByID=ID THEN Null ELSE ModifiedById END,
CreatedByID = CASE WHEN CreatedByID=ID THEN Null ELSE CreatedById END,
DeletedByID = CASE WHEN DeletedByID=ID THEN Null ELSE DeletedById END
WHERE (ModifiedByID = ID OR CreatedByID = ID OR DeletedByID = ID)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...