IF UPDATE () в триггере SQL-сервера - PullRequest
30 голосов
/ 29 января 2010

Если есть:

IF UPDATE (col1)

... в триггере SQL-сервера для таблицы, он возвращает true, только если col1 был изменен или обновлен?

У меня есть обычный запрос на обновление, например

UPDATE table-name 
   SET col1 = 'x', 
       col2 =  'y' 
 WHERE id = 999

Теперь, что меня беспокоит, если ранее «col1» был «x», то снова мы обновили его до «x» IF UPDATE ("col1") триггер вернет True или нет?

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

Ответы [ 8 ]

46 голосов
/ 29 января 2010

Возвращает true, если столбец был обновлен. Обновление означает, что запрос имеет значение SET столбца. То, было ли предыдущее значение таким же, как новое значение, в значительной степени не имеет значения.

UPDATE table SET col = col

это обновление.

UPDATE table SET col = 99

когда col уже имеет значение 99, это также обновление.

10 голосов
/ 29 января 2010

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

2 голосов
/ 19 апреля 2014

Вот быстрый способ просмотреть строки, чтобы увидеть, изменился ли ЛЮБОЙ столбец, прежде чем принимать решение о запуске содержимого триггера. Это может быть полезно, например, когда вы хотите написать запись истории, но не хотите делать это, если ничего не изменилось.

Мы используем это все время в процессах импорта ETL, где мы можем повторно импортировать данные, но если ничего не изменилось в исходном файле, мы не хотим создавать новую запись истории.

CREATE TRIGGER [dbo].[TR_my_table_create_history]
ON [dbo].[my_table] FOR UPDATE AS

BEGIN

    --
    -- Insert the old data row if any column data changed
    --
    INSERT INTO [my_table_history]
    SELECT  d.*
    FROM    deleted d
    INNER JOIN inserted i ON i.[id] = d.[id]
    --
    -- Use INTERSECT to see if anything REALLY changed
    --
    WHERE   NOT EXISTS( SELECT i.* INTERSECT SELECT d.* )

END

Обратите внимание, что этот конкретный триггер предполагает, что ваша исходная таблица (та, которая вызывает триггер) и таблица истории имеют идентичные макеты столбцов.

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

Что вы делаете, проверяете различные значения во вставленных и удаленных таблицах, а не используете updated () (не забудьте учесть нулевые значения). Или вы можете прекратить делать ненужные обновления.

1 голос
/ 08 июля 2015
cREATE TRIGGER boo  ON status2 FOR UPDATE AS 
IF UPDATE (id)
BEGIN
SELECT 'DETECT'; 
END;

UPDATE status2 SET name = 'K' WHERE name= 'T' --no action 
UPDATE status2 SET name = 'T' ,id= 8 WHERE name= 'K' --detect
1 голос
/ 19 апреля 2013

Для быстрого доступа к делу «Нет актуальных обновлений», вам также необходимо вначале проверить, затрагивал ли ваш запрос какие-либо строки:

set nocount on; -- this must be the first statement!
if not exists (select 1 from inserted) and not exists (select 1 from deleted)
  return;
0 голосов
/ 09 ноября 2015

Это сработало для меня

DECLARE @LongDescDirty bit = 0

Declare @old varchar(4000) = (SELECT LongDescription from deleted)
Declare @new varchar(4000) = (SELECT LongDescription from inserted)

if (@old <> @new)
    BEGIN
        SET @LongDescDirty = 1
    END

Update table
  Set LongDescUpdated = @LongDescUpdated

.....

0 голосов
/ 08 сентября 2014
SET NOCOUNT ON;

    declare @countTemp int
    select @countTemp = Count (*) from (
    select City,PostCode,Street,CountryId,Address1 from Deleted
    union
    select City,PostCode,Street,CountryId,Address1 from Inserted
    ) tempTable

    IF ( @countTemp > 1 )

Begin

-- Your Code goes Here
End

-- if any of these  "City,PostCode,Street,CountryId,Address1" got updated then trigger

-- will  work in " IF ( @countTemp > 1 ) " Code)
...