From here: https://stackoverflow.com/questions/19077356/how-to-determine-what-fields-were-update-in-an-update-trigger
create trigger utr_Table1_update on Table1
after update, insert, delete
as
begin
with cte_inserted as (
select id, (select t.* for xml raw('row'), type) as data
from inserted as t
), cte_deleted as (
select id, (select t.* for xml raw('row'), type) as data
from deleted as t
), cte_i as (
select
c.ID,
t.c.value('local-name(.)', 'nvarchar(128)') as Name,
t.c.value('.', 'nvarchar(max)') as Value
from cte_inserted as c
outer apply c.Data.nodes('row/@*') as t(c)
), cte_d as (
select
c.ID,
t.c.value('local-name(.)', 'nvarchar(128)') as Name,
t.c.value('.', 'nvarchar(max)') as Value
from cte_deleted as c
outer apply c.Data.nodes('row/@*') as t(c)
)
insert into Table1_History (ID, Name, OldValue, NewValue)
select
isnull(i.ID, d.ID) as ID,
isnull(i.Name, d.Name) as Name,
d.Value,
i.Value
from cte_i as i
full outer join cte_d as d on d.ID = i.ID and d.Name = i.Name
where
not exists (select i.value intersect select d.value)