Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
Pepro
Starting Member
4 Posts |
Posted - 2008-07-25 : 16:25:03
|
| Let's say that we have a tableCREATE TABLE [dbo].[TestTable1]([Id] [int] IDENTITY(1,1) NOT NULL,[name] [varchar](50) NULL,[abc] [varchar](50) NULL,[RType] [int] NULL)When developers create Data Access stored procedures we create like thiscreate procedure AddUpdTestTable1@name varvhar(50),@abc varchar (50),@Rtype int,@id intasif @Id > 0 --Update update TestTable1 set [name]=@name, [abc] = @abc, [Rtype]= @RType where Id = @idelse insert into TestTable1 ([name],[abc],[Rtype]) values (@name,@abc,@Rtype)That stored procedure is created on th sake of functionallity of to perform further validation on the data base sideBut It was one down side, it updates every field event if it has the same valueBut What if I want to create and audit log that shows me which columns and row has been modified on the db side?I'd tried many approaches of course trying to avoid using dynamic sql construction, innecesary overhead and I came wih this solutionI added a trigger that detects changes and then stores changed column into a a given table like this:create trigger AuditLog on TestTable1with encryptionFOR UPDATEAS BEGIN SET NOCOUNT ON declare @Columns varchar(max) set @Columns = '' select @Columns = @Columns + case TT1.name when TT2.name then '' else 'nombre,' End, @Columns = @Columns + case TT1.abc when TT2.abc then '' else 'abc,' End , @Columns = @Columns + case TT1.Rtype when TT2.Rtype then '' else 'Rtype,' End from inserted TT1 inner join (select Id, [name], abc, RType from deleted) TT2 ON TT1.Id = TT2.Id print @Columns --Perfom audit logEndOf course this trigger only works properly when updating one record it won't show an accurate result when the update is performed on many recordsDoes anyone have a better solution for this? |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
|
|
Pepro
Starting Member
4 Posts |
Posted - 2008-07-25 : 16:51:32
|
| something like:alter trigger Prueba on TestTable1with encryptionFOR UPDATEAS BEGIN SET NOCOUNT ON declare @ColumnChange table (Id int, ColumnsChanged varchar(max)) insert into @ColumnChange select TT1.id, case TT1.nombre when TT2.nombre then '' else 'nombre,' End + case TT1.abc when TT2.abc then '' else 'abc,' End + case TT1.tipo when TT2.tipo then '' else 'tipo,' End from inserted TT1 inner join deleted TT2 ON TT1.Id = TT2.Id --perform some other logic and then sabe to audit log table select * from @columnChange EndBut I want to know is there a way to do this in a generic kind of way .. I mean for every table without the need to write such TSQL but with one expression |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
|
|
Pepro
Starting Member
4 Posts |
Posted - 2008-07-25 : 18:05:34
|
| I managed to create a script that can be used to dynamically create the trigger or to do it with the current table Trigger, I would like to know your opinionalter trigger Prueba on TestTable1with encryptionFOR UPDATEAS BEGIN SET NOCOUNT ONdeclare @ColumnChange table (Id int, ColumnsChanged varchar(max))declare @KeyDef nvarchar(128)SELECT @KeyDef = isc.COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS AS isc INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS kcs ON isc.TABLE_NAME = kcs.TABLE_NAME AND isc.COLUMN_NAME = kcs.COLUMN_NAME AND LEFT(kcs.CONSTRAINT_NAME, 2) = 'PK' WHERE (isc.TABLE_NAME = 'TestTable1')declare @Query varchar(max) set @Query = 'select i.' + @KeyDef + ' as Id,'select @Query = @Query + ' CASE i.' + column_name + ' WHEN d.' + column_name + ' then '''' else ''' + column_name + ','' End + 'from information_schema.columns where table_name= 'TestTable1' and column_name <> @KeyDefset @Query = @Query + ' '''' from #inserted i inner join #deleted d on i.' + @KeyDef +' = d.' + @KeyDef print @query select * into #Inserted from inserted select * into #Deleted from deleted insert into @ColumnChange exec (@query) drop table #Inserted drop table #Deleted --do audit log select * from @ColumnChangeEndToo much overhead??? |
 |
|
|
Pepro
Starting Member
4 Posts |
Posted - 2008-07-25 : 18:08:55
|
| I built the script with table schema in mind ... what happens if the table design changes? we'd need to update the trigger as well... of course it can be encapsulated in a function to return the query string to be executed dinamically |
 |
|
|
|
|
|
|
|