Создание триггера на SQL Server 2008 R2 для перехвата обновления записи - PullRequest
2 голосов
/ 20 июля 2011

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

В любом случае, я создал таблицувызвал Audit_RM00101 следующим образом:

DATE        nchar(10)   
CUSTNMBR    char(15)    
CUSTNAME    char(65)    
UPSZONE     char(3) 
SALSTERR    char(15)    
USERID      nchar(100)

Я хочу получить те же поля из таблицы, которую я хочу проверить, поэтому я написал триггер следующим образом:

CREATE TRIGGER CatchCustomerRegionUpdate
ON RM00101
FOR UPDATE
AS
DECLARE @UserID VARCHAR(128)
SELECT @UserID = system_user
INSERT INTO audit_RM00101 
SELECT DATE, CUSTNMBR, CUSTNAME, UPSZONE, SALSTERR, @UserID FROM UPDATED

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

Что я здесь не так делаю?

Спасибо.

Ответы [ 3 ]

5 голосов
/ 20 июля 2011

в триггере вы получаете таблицы DELETED и INSERTED, UPDATED нет, поэтому замените FROM UPDATED на FROM INSERTED

и попробуйте исправить столбец USERID, вашaudit_RM00101.USERID - это nchar(100), в то время как @UserID - это VARCHAR(128).

РЕДАКТИРОВАТЬ на основе комментария OP: Ах, поэтому нет возможности провести аудит, когдатаблица обновляется с помощью триггера?

  • в триггере при удалении , DELETED заполняется, но INSERTED пусто
  • в триггере при обновлении , DELETED заполняется исходным значением, а INSERTED заполняется недавно обновленными значениями
  • в триггере при вставке , DELETED пусто, но INSERTED имеет недавно вставленные значения
3 голосов
/ 20 июля 2011

В SQL Server нет UPDATED;просто inserted и deleted.Также имеет смысл добавить IF @@ROWCOUNT = 0 RETURN в самом начале тела тригера.Когда происходит UPDATE, таблицы inserted и deleted не являются пустыми.Вы можете добавить следующий код, чтобы убедиться, что вы обрабатываете UPDATE, а не insert/delete:

IF EXISTS(SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted) 
BEGIN
 -- handle update
END ;

Это не очень важно для вашего триггера, потому что вы указываете только FOR UPDATE, было бы важно, если бы выимел, например, FOR UPDATE, INSERT, DELETE.

1 голос
/ 03 марта 2014

у нас есть только две магические таблицы с именами INSERTED и DELETED

косвенное обновление - это оператор Delete, за которым следует оператор Insert. поэтому вы должны обновить значение столбца, которое присутствует в INSERTED.

CREATE TRIGGER CatchCustomerRegionUpdate
ON RM00101
AFTER UPDATE
AS
BEGIN
    DECLARE @INSERTED INT, @DELETED INT
    SET @INSERTED = SELECT COUNT(*) FROM INSERTED
    SET @DELETED = SELECT COUNT(*) FROM DELETED

    IF @INSERTED = 1 AND @DELETED = 1
    BEGIN
        UPDATE TABLE1
        SET COL1 = INSERTED_COL1
        WHERE IDCOL = INSERTED_IDCOL

    END

END
...