TSql Trigger нужно запускать только для столбцов, значения которых изменились - PullRequest
9 голосов
/ 05 января 2010

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

IF UPDATE(column-name)

Эта часть отлично работает. Однако оказывается, что существуют другие части кода, которые обновляют строки, устанавливая каждое отдельное значение независимо от того, изменилось ли значение на самом деле или нет, и это вызывает срабатывание триггера для частей, которые были «обновлены», но значения которых фактически не изменились совсем.

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

Ответы [ 4 ]

14 голосов
/ 05 января 2010
IF EXISTS (SELECT *
          FROM
             INSERTED I JOIN DELETED D ON I.Key = D.Key
          WHERE
             I.Col <> D.Col)
...

или используйте переменную таблицы для кэширования, чтобы избежать повторного использования I и D.

SELECT
    CASE WHEN I.Col1 <> D.Col1 THEN 1 ELSE 0 END AS Col1Diff,
    CASE WHEN I.Col2 <> D.Col2 THEN 1 ELSE 0 END AS Col2Diff,
    ...
FROM
    INSERTED I JOIN DELETED D ON I.Key = D.Key

или объедините идеи для проверки всех изменений и выхода из триггера

7 голосов
/ 05 января 2010

Как уже говорили другие, вы должны использовать таблицы INSERTED и DELETED.

Вот что я сделал вместо:

IF UPDATE(col1) OR UPDATE(col2))
UPDATE table1
SET col3 = 1
FROM INSERTED
WHERE table1.Id = INSERTED.Id

Я сделал:

IF UPDATE(col1) OR UPDATE(col2))
 UPDATE table1
 SET col3 = 1
 FROM 
  (SELECT Id, col1, col2 FROM INSERTED 
   EXCEPT 
  SELECT Id, col1, col2 FROM DELETED) AS ALTERED
 WHERE table1.Id = ALTERED.Id

Использование EXCEPT выбирает отдельные строки, в которых интересующие меня столбцы не существуют в удаленной (или исходной таблице) данных (то есть значение этих столбцов изменилось). Я не знаю, является ли это лучшим ответом, но похоже, что он работает.

4 голосов
/ 05 января 2010

Столбец обновлен. То, что старое значение и новое значение были одинаковыми, это просто деталь. Я думаю, что ваше единственное решение - сравнить значения между вставленными и удаленными псевдотаблицами.

2 голосов
/ 05 января 2010

Не то, что я знаю. INSERTED и DELETED существуют по какой-то причине, и сравнение между ними кажется мне лучшим вариантом.

IF UPDATE() просто сообщает вам, была ли сделана вставка или обновление попытка , и даже не отражает, была ли эта попытка успешной или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...