Как определить, изменилось ли что-либо в триггере обновления в t-sql

17

Как определить, что-то изменилось в триггере UPDATE? Например, у меня есть таблица с именем person с только одним столбцом NAME, которое содержит значение «Mike». Если я запустил

UPDATE person SET NAME = 'Mike' 

как я могу определить в триггере обновления ничего не изменилось? Я знаю о     ОБНОВЛЕНИЕ (COL) , но я не хочу перебирать столбцы. Есть ли другой способ сделать это?

    
задан Marian Zagoruiko 11.05.2012 в 13:15
источник

2 ответа

32

Обновление (столбец) просто указывает, что столбец участвовал в обновлении, но не изменил его значение. Например,

update Person SET Name = Name

возвращает true в update (name), хотя имя не было изменено ни в одной строке.

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

insert into logTable (ID)
select a.ID
from
(
   select * from Inserted
   except
   select * from Deleted
) a

Добавленная выгода заключается в том, что это работает и для вставок, потому что Deleted будет пустым и все строки из вставленного будут возвращены.

    
ответ дан Nikola Markovinović 11.05.2012 в 15:12
источник
  • Спасибо, это работает для меня! –  Marian Zagoruiko 14.05.2012 в 12:06
14

Ссылаясь на ответ Ариона выше:

Обязательно сравните записи по их первичному ключу, когда SELECT из JOIN, поскольку таблицы INSERTED и DELETED могут содержать более одной записи, которая, если игнорируется, может привести к неправильным результатам запроса и негативному влиянию на производительность БД.

-- Anrion's answer - slightly modified
CREATE TRIGGER UpdatedTriggerName
ON person -- table name
AFTER UPDATE
AS 
IF EXISTS (
    SELECT
        *
    FROM
        INSERTED I
        JOIN
        DELETED D
            -- make sure to compare inserted with (same) deleted person
            ON D.ID = I.ID 
            AND D.NAME <> I.NAME -- only persons with changed name
    )
print 'something'
GO
    
ответ дан DeMo 24.09.2013 в 18:12
источник
  • Отличный ответ! –  Carl R 24.05.2015 в 15:09