I am writing an instead of trigger for updates that does some auditing and then should only perform the actual update when any column changes, except two. I have a query that does this, but the problem is maintenance. The query has to list out every column in the table several times and this table (and several others like it) are likely to change. This puts a very large burden on the programmer every time any changes are made. Here is what the query looks like:
create trigger member_history_trigger on Member
instead of update
as
begin
insert into MemberHistory (Name, Address, RevisedBy, RevisedDate)
select d.Name, d.Address, d.RevisedBy, d.RevisedDate
from DELETED d
join INSERTED i on (d.memberid = i.memberid)
where (d.Name != i.Name or d.Address != i.Address);
update m
set m.Name = i.Name
, m.Address = i.Address
, m.RevisedBy = i.RevisedBy
, m.RevisedDate = i.RevisedDate
from INSERTED i left join Member m on (i.MemberID = m.MemberID)
where (m.Name != i.Name or m.Address != i.Address)
end
As you can see above, I only want to perform an update when a field other than RevisedBy or RevisedOn changes. This example looks simple, but in reality this table has 20 fields and there are 10 other tables like it for which this same thing must be done.
Can I do this same thing, but without listing out the names of each column? Is there a way to say, “Update every column if any column has changed other than RevisedBy or RevisedDate?” If there is, I would never have to look at these queries ever again.
Nope.
As a rule, it’s difficult to indicate fields without being explicit for very good reasons, such as the ability (and frequent occurence of) table structure changes.
I’m not aware of any method for specifying a subset of columns without using either dynamic SQL (dangerous, and downright terrifying inside a trigger) or explicitly listing them out.
It’s a pain, but it’s a proper practice and will prevent all sorts of unexpected consequences.