• Sorry I forgot one more thing:  I noticed that Karen's tbl_log (and the code that writes to it) doesn't include the PK(s) for the table the change came from.  This makes it difficult at best to use the information gathered in your audit table to trace back to the row in the base table that the change was performed on.

    This was not difficult to solve.  In my particular database, I know I have composite PK's with a maximum of 5 columns.  So I added PK1, PK2, PK3, PK4 and PK5 columns to my version of tbl_log, datatypes of varchar(60) or so.  Then in the trigger code, just before spinning through the columns in the table to see which ones have changed, I get the PK column values like so:

    --Loop through the PK columns for the table and grab values from the temp tables for each

    select @PKpos = min(ordinal_position), @PKposmax = max(ordinal_position)

           from information_schema.key_column_usage

           where objectproperty(object_id(constraint_name),''IsPrimaryKey'') = 1

           and table_name = '''+@TableName+'''

    while @PKpos <= @PKposmax

           begin

                  select @PKval = null

                  select @PKcolname = quotename(column_name)

                         from information_schema.key_column_usage

                         where objectproperty(object_id(constraint_name),''IsPrimaryKey'') = 1

                         and table_name = '''+@TableName+''' and ordinal_position = @PKpos

                 

                  if exists(select * from #inserted'+@VarRandom+')

                         select @subsql = N''select @PKval = convert(varchar(60), d.''

                               + @PKcolname+'') from #inserted'+@VarRandom+' d ''

                  else

                         select @subsql = N''select @PKval = convert(varchar(60), d.''

                               + @PKcolname+'') from #deleted'+@VarRandom+' d ''

     

                         exec sp_executesql @subsql, N''@PKval varchar(60) output'', @PKval output

                 

                  if @PKpos = 1

                         set @PK1val = @PKval

                  else if @PKpos = 2

                         set @PK2val = @PKval

                  else if @PKpos = 3

                         set @PK3val = @PKval

                  else if @PKpos = 4

                         set @PK4val = @PKval

                  else if @PKpos = 5

                         set @PK5val = @PKval

                        

                  select @PKpos = @PKpos+1

           end

    As you might guess I then wrote the @PK1val, @PK2val,... values to my ChangeLog table in corresponding columns.  It was not really necessary to record what the column name was for each part of the composite because I can derive that easily by the table name.  I can now join the ChangeLog table directly back to the row in the base table where the change was originally performed for reporting.