Hello -I have a trigger on a table that I am using to populate an archive table. The archive table will be used database-wide to track changes to the tables. Essentially, I have to track the old and new values for any changes to a table.When my trigger fires and I update only a single column or all the columns, the archive table gets the correct values/rows. For example, if my update is for a single column, ony one row gets added to the archive table. If I update all columns (and suppose there are 12 columns), then I get 12 rows in the archive table. The problem is when I update a subset of the columns (2 or 5 or whatever). When I do this, I get multiple rows of duplicates for one of the columns.Below is my table and trigger code.CREATE TABLE [dbo].[TestTrigger]( [PKID] [int] IDENTITY(1,1) NOT NULL, [TheName] [varchar](50) NULL, [TheNumber] [int] NULL, [TheDate] [datetime] NULL, [TheBit] [bit] NULL, [TheNewCol] [varchar](50) NULL) ON [PRIMARY]CREATE TABLE [dbo].[Archive_TestTrigger]( [PKID] [int] IDENTITY(1,1) NOT NULL, [TableName] [varchar](30) NULL, [PrimaryKey] [int] NULL, [ColumnName] [varchar](30) NULL, [ColumnType] [varchar](10) NULL, [OldValue] [varchar](50) NULL, [NewValue] [varchar](50) NULL, [createDt] [datetime] NULL) ON [PRIMARY]Create Trigger [dbo].[trg_Update_Test] on [dbo].[TestTrigger] for updateasdeclare @bit int , @field int , @char int, @colName nvarchar(50) declare @sqlCmd nvarchar(2000)declare @TableName nvarchar(30)set @TableName = 'TestTrigger'select @field = 0Select * into #Inserted from insertedSelect * into #Deleted from deletedwhile @field < (select max(colid) from syscolumns where id = (select id from sysobjects where name = 'TestTrigger'))begin select @field = @field + 1 select @bit = (@field - 1 )% 8 + 1 select @bit = power(2,@bit - 1) select @char = ((@field - 1) / 8) + 1 select @char as AtChar, @field as AtField, @bit as AtBit -- debug code to check the bits that are tested. if substring(COLUMNS_UPDATED(),@char, 1) & @bit > 0 set @colName = (select --@field, name as ColumnName from syscolumns where colid = @field and id = (select id from sysobjects where name = 'TestTrigger')) set @sqlCmd = 'INSERT INTO dbo.Archive_TestTrigger ' set @sqlCmd = @sqlCmd + '(TableName, PrimaryKey, ColumnName, ColumnType, OldValue, NewValue, CreateDt) ' set @sqlCmd = @sqlCmd + ' SELECT ' + quotename(@TableName, '''') + ' AS TableName, ' + 'p.PKID as PrimaryKey, ' set @sqlCmd = @sqlCmd + quotename(@colName, '''') + ' AS ColumnName, space(5) as columnType, ' set @sqlCmd = @sqlCmd + 'd.' + @colName + ' AS OldValue, i.' + @colName + ' AS NewValue,' set @sqlCmd = @sqlCmd + 'GetDate() as CreateDt ' set @sqlCmd = @sqlCmd + ' FROM dbo.TestTrigger as p INNER JOIN #Deleted as d on p.pkID = d.pkID ' set @sqlCmd = @sqlCmd + ' INNER JOIN #inserted as i on p.pkID = i.pkID' execute sp_executesql @sqlCmd end
If I execute an update like this:update dbo.TestTrigger Set TheName = 'Another updated name value', TheNewCol = 'Some updated text' where pkID = 1
The following is the result in the Archive table, which shows 4 rows for the TheName column and one for TheNewCol:PKID TableName PrimaryKey ColumnName ColumnType OldValue NewValue createDt1 TestTrigger 1 TheName Updated name value Another updated name value 2009-10-06 11:44:35.6002 TestTrigger 1 TheName Updated name value Another updated name value 2009-10-06 11:44:35.6003 TestTrigger 1 TheName Updated name value Another updated name value 2009-10-06 11:44:35.6034 TestTrigger 1 TheName Updated name value Another updated name value 2009-10-06 11:44:35.6035 TestTrigger 1 TheNewCol Are we still getting lots of extra rows? Some updated text 2009-10-06 11:44:35.610
If anyone has any thoughts here, I'd appreciate it.Thanks, - will