all groups > sql server (alternate) > march 2005 >
You're in the

sql server (alternate)

group:

audit trail triggers


audit trail triggers Zlatko Matiæ
3/31/2005 8:10:46 PM
sql server (alternate):
Hello.

I tried to implement audit trail, by making an audit trail table with the
following fileds:
TableName,FieldName,OldValue,NewValue,UpdateDate,type,UserName.
Triggers on each table were set to do the job and everything was fine except
that in the audit trail you couldn't know which row exacltly was
updated/inserted/deleted...Therefore I introduced 3 additional columnes
(RowMark1, RowMark2, RowMark3) which should identify the
inserted/updated/deleted row.
For example, RowMark1 could be foreign key, RowMark2 could be primary key,
and RowMark3 could be autonumber ID.
But, when I have several rows updated, RowMark columnes values are identical
in all rows in the audit trail table! What is wrong with my code, and how to
solve it ?

Thank you in advance!


CREATE TRIGGER Trigger_audit_TableName
ON dbo.TableName
FOR DELETE, INSERT, UPDATE
AS BEGIN
declare @type nvarchar(20) ,
@UpdateDate datetime ,
@UserName nvarchar(100),
@RowMark1 nvarchar (100),
@RowMark2 nvarchar (100),
@RowMark3 nvarchar (100)

if exists (select * from inserted) and exists (select * from
deleted)
select @type = 'UPDATE',
@RowMark1=d.ForeignKeyField,@RowMark2=d.PrimaryKeyField,@RowMark3=d.ID
from deleted d
else if exists (select * from inserted)
select @type = 'INSERT',
@RowMark1=i.ForeignKeyField,@RowMark2=i.PrimaryKeyField,@RowMark3=i.ID
from inserted i
else
select @type = 'DELETE',
@RowMark1=d.ForeignKeyField,@RowMark2=d.PrimaryKeyField,@RowMark3=d.ID
from deleted d

select @UpdateDate = getdate() ,
@UserName = USER


/*The following code is repeated for every field in a table*/
if update (FieldName) or @type = 'DELETE'
insert dbo.AUDIT_TRAIL (TableName, FieldName, OldValue, NewValue,
UpdateDate, UserName, type,RowMark1,RowMark2,RowMark3)
select 'Descriptive Table Name', convert(nvarchar(100), 'Descriptive
Field Name'),
convert(nvarchar(1000),d.FieldName),
convert(nvarchar(1000),i.FieldName),
@UpdateDate, @UserName, @type, @RowMark1, @RowMark2,
@RowMark3
from inserted i
full outer join deleted d
on i.ID = d.ID
where (i.FieldName <> d.FieldName
or (i.FieldName is null and d.FieldName is not null)
or (i.FieldName is not null and d.FieldName is null))

END





Re: audit trail triggers Erland Sommarskog
3/31/2005 9:52:59 PM
Zlatko Matiæ (zlatko.matic1@sb.t-com.hr) writes:
[quoted text, click to view]

Of course:

[quoted text, click to view]

If deleted contains 15 rows, how would @RowMark1 get more than one value?

Yes, triggers fires once per statement.

--
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

Books Online for SQL Server SP3 at
Re: audit trail triggers Hugo Kornelis
3/31/2005 11:13:40 PM
[quoted text, click to view]

Hi Zlatko,

A trigger is fired once per statement execution, not once per row
affected. The changes you made, like for example this one:

[quoted text, click to view]

will set the variables to the values for one of the rows that were
affected by the update. This variable is then used in all inserts to the
audit table!

You should forget the @RowMark1, -2, and -3 variables. Instead, change
the code to insert audit data to something like this:

insert dbo.AUDIT_TRAIL (TableName, FieldName, OldValue, NewValue,
UpdateDate, UserName, type,RowMark1,RowMark2,RowMark3)
select 'Descriptive Table Name', convert(nvarchar(100), 'Descriptive
Field Name'),
convert(nvarchar(1000),d.FieldName),
convert(nvarchar(1000),i.FieldName),
@UpdateDate, @UserName, @type,
COALESCE (d.ForeignKeyField, i.ForeignKeyField),
COALESCE (d.PrimaryKeyField, i.PrimaryKeyField),
COALESCE (d.ID, i.ID)
from inserted i
full outer join deleted d
on i.ID = d.ID
where (i.FieldName <> d.FieldName
or (i.FieldName is null and d.FieldName is not null)
or (i.FieldName is not null and d.FieldName is null))

I'd like to add that I'm not very fond of your audit table design. I
personally prefer to use several audit tables: one for each table that
needs auditing, with the same columns, plus extra columns such as
DatetimeOfChange (added as extra column to the primary key) and userid.
This table will receive a complete copy of a row's data whenever it is
changed. But hey - if this design works for you, then by all means use
it.

Best, Hugo
--

Re: audit trail triggers Zlatko Matic
4/1/2005 10:55:12 AM
Thanks.

"Hugo Kornelis" <hugo@pe_NO_rFact.in_SPAM_fo> je napisao u poruci interesnoj
grupi:9hpo41hcd4b2gifouvm3o13pj48r3ereqb@4ax.com...
[quoted text, click to view]

AddThis Social Bookmark Button