INSTEAD OF UPDATE Триггер - возможно ли это? - PullRequest
12 голосов
/ 24 марта 2012

Я делаю некоторые изменения в унаследованном приложении, построенном на SQL Server 2000, не говоря уже о том, что я хочу сделать абсолютный минимум только из-за страха, что все это может развалиться.

У меня есть большая таблица пользователей tbUsers с флагом BIT для IsDeleted. Я хочу заархивировать все текущие и будущие записи пользователей IsDeleted = 1 в мою архивную таблицу tbDeletedUsers.

Перемещение удаленных в данный момент пользователей является простым, однако я хочу, чтобы способ переместить всех будущих пользователей, где установлен флаг IsDeleted. Я мог бы использовать стандартный триггер AFTER для столбца, однако я планирую добавить некоторые ограничения в таблицу tbUser, которые могут нарушить это, что я хотел бы, чтобы мой триггер INSTEAD OF UPDATE сработал и переместил запись в таблицу архива? 1005 *

Полагаю, мой вопрос ... возможно ли вызвать триггер INSTEAD OF UPDATE при обновлении отдельного столбца? Это то, что я до сих пор:

 CREATE TRIGGER trg_ArchiveUsers
 INSTEAD OF UPDATE ON tbUsers
 AS 
    BEGIN
      ...
    END
 GO

Если это так, пример (совместимый с SQL 2000) был бы очень признателен!

1 Ответ

14 голосов
/ 25 марта 2012

Используя тест UPDATE(<em>columnname</em>), вы можете проверить в триггере, был ли обновлен определенный столбец (и затем выполнить определенные действия), но у вас не может быть триггера fire только при обновлении определенного столбца. Он будет срабатывать, как только будет выполнено обновление, независимо от того, какой столбец был целью обновления.

Итак, если вы считаете, что вам нужно использовать триггер INSTEAD OF UPDATE, вам нужно реализовать в нем два вида действий:

1) вставить в tbDeletedUsers + удалить из tbUsers - когда IsDeleted обновляется (или, точнее, обновляется и устанавливается на 1);

2) обычно обновляется tbUsers - когда IsDeleted не обновляется (или не обновляется, но не установлен на 1).

Поскольку более одной строки можно обновить с помощью одной инструкции UPDATE, вам также может понадобиться учесть, что для некоторых строк IsDeleted может быть установлено 1, а для других - нет.

Я не большой поклонник триггеров INSTEAD OF, но если бы мне действительно пришлось использовать один для такой задачи, как ваша, я мог бы пропустить тест UPDATE() и реализовать триггер следующим образом:

CREATE TRIGGER trg_ArchiveUsers
ON tbUsers
INSTEAD OF UPDATE
AS
BEGIN
  UPDATE tbUsers
  SET
    <i>column</i> = INSERTED.<i>column</i>,
    …
  FROM INSERTED
  WHERE INSERTED.<i>key</i> = tbUsers.<i>key</i>
    AND INSERTED.IsDeleted = 0
  ;
  DELETE FROM tbUsers
  FROM INSERTED
  WHERE INSERTED.<i>key</i> = tbUsers.<i>key</i>
    AND INSERTED.IsDeleted = 1
  ;
  INSERT INTO tbDeletedUsers (<i>columns</i>)
  SELECT <i>columns</i>
  FROM INSERTED
  WHERE IsDeleted = 1
  ;
END
...