Important alert: (current site time 7/15/2013 7:53:36 PM EDT)
 

VB icon

Creating the Audit Trigger

Email
Submitted on: 4/12/2004 2:23:29 AM
By: Kazi Khalid 
Level: Intermediate
User Rating: By 4 Users
Compatibility: SQL Server 2000, SQL Server 7.0
Views: 23755
(About the author)
 
     Create an audit trigger on the tables in order to record the changes to the data by the user
 
code:
Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
 
Terms of Agreement:   
By using this code, you agree to the following terms...   
  1. You may use this code in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
  2. You MAY NOT redistribute this code (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.   
  3. You may link to this code from another website, but ONLY if it is not wrapped in a frame. 
  4. You will abide by any additional copyright restrictions which the author may have placed in the code or code's description.
				
--**************************************
-- Name: Creating the Audit Trigger
-- Description:Create an audit trigger on the tables in order to record the changes to the data by the user
-- By: Kazi Khalid
--
-- Inputs:It will put out an error message if there is no primary key on the table
--
-- Assumes:You will need to change @TableName to match the table to be audit traile
--
--This code is copyrighted and has-- limited warranties.Please see http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=829&lngWId=5--for details.--**************************************

/*
This trigger audit trails all changes made to a table.
It will place in the table Audit all inserted, deleted, changed columns in the table on which it is placed.
It will put out an error message if there is no primary key on the table
You will need to change @TableName to match the table to be audit trailed
*/
--Set up the tables
if exists (select * from sysobjects where id = object_id(N'[dbo].[Audit]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[Audit]
go
create table Audit (TableName varchar(128), FieldName varchar(128), OldValue varchar(1000), NewValue varchar(1000), UpdateDate datetime, UserName varchar(128))
go
if exists (select * from sysobjects where id = object_id(N'[dbo].[trigtest]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[trigtest]
go
create table trigtest (i int not null, j int not null, s varchar(10), t varchar(10))
go
alter table trigtest add constraint pk primary key (i, j)
go
create trigger tr_trigtest on trigtest for insert, update, delete
as
declare @bit int ,
	@field int ,
	@maxfield int ,
	@char int ,
	@fieldname varchar(128) ,
	@TableName varchar(128) ,
	@PKCols varchar(1000) ,
	@sql varchar(2000), 
	@UpdateDate varchar(21) ,
	@UserName varchar(128)
	
	select @TableName = 'trigtest'
	-- date and user
	select 	@UserName = system_user ,
		@UpdateDate = convert(varchar(8), getdate(), 112) + ' ' + convert(varchar(12), getdate(), 114)
	-- get list of columns
	select * into #ins from inserted
	select * into #del from deleted
	
	-- Get primary key columns for full outer join
	select	@PKCols = coalesce(@PKCols + ' and', ' on') + ' i.' + c.COLUMN_NAME + ' = d.' + c.COLUMN_NAME
	from	INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,
		INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
	where 	pk.TABLE_NAME = @TableName
	and	CONSTRAINT_TYPE = 'PRIMARY KEY'
	and	c.TABLE_NAME = pk.TABLE_NAME
	and	c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
	
	if @PKCols is null
	begin
		raiserror('no PK on table %s', 16, -1, @TableName)
		return
	end
	
	select @field = 0, @maxfield = max(ORDINAL_POSITION) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName
	while @field < @maxfield
	begin
		select @field = min(ORDINAL_POSITION) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName and ORDINAL_POSITION > @field
		select @bit = (@field - 1 )% 8 + 1
		select @bit = power(2,@bit - 1)
		select @char = ((@field - 1) / 8) + 1
		if substring(COLUMNS_UPDATED(),@char, 1) & @bit > 0
		begin
			select @fieldname = COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName and ORDINAL_POSITION = @field
			select @sql = 		'insert Audit (TableName, FieldName, OldValue, NewValue, UpdateDate, UserName)'
			select @sql = @sql + 	' select ''' + @TableName + ''''
			select @sql = @sql + 	',''' + @fieldname + ''''
			select @sql = @sql + 	',convert(varchar(1000),d.' + @fieldname + ')'
			select @sql = @sql + 	',convert(varchar(1000),i.' + @fieldname + ')'
			select @sql = @sql + 	',''' + @UpdateDate + ''''
			select @sql = @sql + 	',''' + @UserName + ''''
			select @sql = @sql + 	' from #ins i full outer join #del d'
			select @sql = @sql + 	@PKCols
			select @sql = @sql + 	' where i.' + @fieldname + ' <> d.' + @fieldname 
			select @sql = @sql + 	' or (i.' + @fieldname + ' is null and d.' + @fieldname + ' is not null)' 
			select @sql = @sql + 	' or (i.' + @fieldname + ' is not null and d.' + @fieldname + ' is null)' 
			
			exec (@sql)
		end
	end
go
insert trigtest select 1,1,'hi', 'bye'
insert trigtest select 2,2,'hi', 'bye'
insert trigtest select 3,3,'hi', 'bye'
update trigtest set s = 'hibye' where i <> 1
update trigtest set s = 'bye' where i = 1
update trigtest set s = 'bye' where i = 1
update trigtest set t = 'hi' where i = 1
select * from Audit
select * from trigtest
go
drop table Audit
go
drop table trigtest
go


Other 2 submission(s) by this author

 


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this code (in the Intermediate category)?
(The code with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments

4/26/2004 10:44:06 PMdotNETJunkie

Although this trigger may work, I would never execute a trigger such as this into a production environment.
(If this comment was disrespectful, please report it.)

 
6/7/2004 2:32:02 PM

I am trying to implement this code to audit a table. I keep getting an error in SQL analyzer. That says
(If this comment was disrespectful, please report it.)

 
6/7/2004 3:26:46 PM

I have the trigger created now, but when I insert a record. it gives me the No 'PK' on table" error. I do have a Primary Key on the table however.
(If this comment was disrespectful, please report it.)

 
6/15/2004 8:05:03 AM

So, if this trigger affects overall performance on a production database, as you said dotNetJunkie, and i agree with you, how would you keep track of what data the user has changed to make a summary of the changes of the day?

Im developing a database which will be in 2 different places and until now i cannot find a way to update certain tables....

Any ideas would be appreciate
My email: murilo.filho@asa-sistemas.com

Thanx developer friends
(If this comment was disrespectful, please report it.)

 
12/27/2004 10:43:37 AMMicrosoftMatt

I like the code. Nice submission. The code works nice for recording inserts and updates. Two things I noticed isn't it didn't record "deletes" when I used it and as an added feature I'd like to see it store the value of the primary key. From an audit standpoint if 5 rows in the table have a value of 0 and they all get updated to 1 the audit table doesn't identify which row in the table was changed. Regarding the production environment I'm thinking dotNetJunkie was implying that the volume and size of the table could be a detriment. This may be negligible if your talking about audits on low volume high importance table.
(If this comment was disrespectful, please report it.)

 
6/23/2005 4:35:46 PMBryan Bensing

This was copied from a website... same examples and everything
(If this comment was disrespectful, please report it.)

 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular code, please click here instead.)
 

To post feedback, first please login.