Нет специального оператора, который можно было бы запустить, который бы точно указывал, какие столбцы изменились, но, тем не менее, запрос написать несложно:
DECLARE @Updates TABLE
(
OldFoo varchar(50),
NewFoo varchar(50),
OldBar varchar(50),
NewBar varchar(50)
)
UPDATE FooBars
SET <some_columns> = <some_values>
OUTPUT deleted.foo, inserted.foo, deleted.bar, inserted.bar INTO @Updates
WHERE <some_conditions>
SELECT *
FROM @Updates
WHERE OldFoo != NewFoo
OR OldBar != NewBar
Если вы пытаетесь на самом деле сделать что-то в результате этих изменений, то лучше всего написать триггер:
CREATE TRIGGER tr_FooBars_Update
ON FooBars
FOR UPDATE AS
BEGIN
IF UPDATE(foo) OR UPDATE(bar)
INSERT FooBarChanges (OldFoo, NewFoo, OldBar, NewBar)
SELECT d.foo, i.foo, d.bar, i.bar
FROM inserted i
INNER JOIN deleted d
ON i.id = d.id
WHERE d.foo <> i.foo
OR d.bar <> i.bar
END
(Конечно, вы, вероятно, захотите сделать больше, чем это, в триггере, но есть пример очень упрощенного действия)
Вы можете использовать COLUMNS_UPDATED
вместо UPDATE
, но я нахожу это болезненным, и он все равно не скажет вам, какие столбцы действительно изменили , какие столбцы были включены в UPDATE
заявление. Так, например, вы можете написать UPDATE MyTable SET Col1 = Col1
, и он все равно скажет вам, что Col1
был обновлен, хотя на самом деле не было изменено ни одного отдельного значения. При написании триггера вам необходимо на самом деле проверить отдельные значения до и после, чтобы убедиться, что вы получаете реальные изменения (если это то, что вы хотите).
P.S. Вы также можете UNPIVOT
, как говорит Роб, но вам все равно нужно явно указать столбцы в предложении UNPIVOT
, это не волшебство.