Hello.
I tried to implement audit trail, by making an audit trail table with the
following fileds:
TableName,FieldName,OldValue,NewValue,UpdateDate,t ype,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.PrimaryKey Field,@RowMark3=d.ID
from deleted d
else if exists (select * from inserted)
select @type = 'INSERT',
@RowMark1=i.ForeignKeyField,@RowMark2=i.PrimaryKey Field,@RowMark3=i.ID
from inserted i
else
select @type = 'DELETE',
@RowMark1=d.ForeignKeyField,@RowMark2=d.PrimaryKey Field,@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 3 6247
On Thu, 31 Mar 2005 20:10:46 +0200, Zlatko Matić wrote: 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!
Hi Zlatko,
A trigger is fired once per statement execution, not once per row
affected. The changes you made, like for example this one:
select @type = 'UPDATE', @RowMark1=d.ForeignKeyField,@RowMark2=d.PrimaryKey Field,@RowMark3=d.ID from deleted d
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
--
(Remove _NO_ and _SPAM_ to get my e-mail address)
Zlatko Matić (zl***********@sb.t-com.hr) writes: But, when I have several rows updated, RowMark columnes values are identical in all rows in the audit trail table!
Of course:
@RowMark1=d.ForeignKeyField,@RowMark2=d.PrimaryKe yField,@RowMark3=d.ID from deleted d
If deleted contains 15 rows, how would @RowMark1 get more than one value?
Yes, triggers fires once per statement.
--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se
Books Online for SQL Server SP3 at http://www.microsoft.com/sql/techinf...2000/books.asp
Thanks.
"Hugo Kornelis" <hugo@pe_NO_rFact.in_SPAM_fo> je napisao u poruci interesnoj
grupi:9h********************************@4ax.com.. . On Thu, 31 Mar 2005 20:10:46 +0200, Zlatko Matić wrote:
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!
Hi Zlatko,
A trigger is fired once per statement execution, not once per row affected. The changes you made, like for example this one:
select @type = 'UPDATE',
@RowMark1=d.ForeignKeyField,@RowMark2=d.PrimaryKey Field,@RowMark3=d.ID from deleted d
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 --
(Remove _NO_ and _SPAM_ to get my e-mail address) This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Raphael Gluck |
last post by:
Hi,
Is it possible for one to program one's pages as such that when a database
table is updated over the web, via a form, that an e-mail confirmation is
sent to a specified address, notifying...
|
by: Keith |
last post by:
Hi
I am developing an ASP application which will interact with a SQL database.
A requirement of the application is that there is a full audit trail of any
modifications to data.
I am...
|
by: Zlatko Matić |
last post by:
I tried to implement triggers for filling audit-trail table on this way.
Everything works fine as long as I don't update the primary key field value.
When I try to update PK value, an error...
|
by: Jim M |
last post by:
I've been playing with Allen Browne's audit code and found it very
useful. I need to track record insertions, deletions, and edits for
several tables. I am planning to replace Access with Microsoft...
|
by: Parag |
last post by:
Hello,
I have been assigned the task to design the audit trail for the ASP.NET web
application. I don't know what the best practices for such audit trails are.
Our application one dedicated user...
|
by: JimLad |
last post by:
Hi,
I've been tasked with reviewing the Authentication and Auditing of an
application and database.
ASP/ASP.NET 1.1 app with SQL Server 2000 database. Separate audit trail
database on same...
|
by: hary08 |
last post by:
I have a module copied ftom this site, here it is:
Option Compare Database
Option Explicit
Public Function AuditTrail()
On Error GoTo Err_Audit_Trail
'ACC2000: How to Create an Audit...
|
by: hary08 |
last post by:
im doing a database for Hospital Admission, I have a log in form which prompt user for a password. The source of log in is to look for the values in my Table tblEmployees and match user name and...
|
by: rockdc1981 |
last post by:
I dont it is possible to put this codes together.. I want to prompt the user to save the record and at the same time have a log of audit trail. the codes work out fine separately.
Code for Audit...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
| |