SQL Server – Data Change Audit Plan

auditsql server

My company is changing from a distributed Access Database model to using a centralized SQL Database. The datatables were designed such that all of the tables have a modified date. In discussion it was suggested that since we will be creating a trigger on each table to handle the modified date perhaps we should have the trigger also log some information to an audit table.

Is this the best way to setup auditing so that we can track who is changing information or is there a better way? Links to articles on the subject are welcome.

For the audit I'm looking at capturing the table name, column name, date modified, row id and the username of the person making the change. Is there any information I'm not thinking of that I should be capturing that might help me avoid future pit falls?

Best Answer

Don't bother tracking audit data on a per-field basis. It's much easier to have an audit table with the same structure as the main table and timestamp and user information tracked on the table.

This architecture has a few advantages:

  • You can easily create a view across the main table and audit table to show a complete history includint current versions.
  • It is relatively simple to implement the audit triggers - in fact if you hae a large number of tables you can write a utility to generate them from the system data dictionary.
  • The audit tables can be put on a separate disk to reduce the I/O load on the disk with the main tables.
  • It's very easy to reconstruct an as-at version of the record, rather than having to apply a list of field-level changes in reverse.

Audit information should include at least: user who created/changed the record, date/time of the creation/change, nature of change (insert, update, delete). You may want to use logical deletion (i.e. a 'Deleted' flag) if you have the option of doing so. Otherwise you need to capture the user and date/time from the session and put these on the deletion record, probably along with the last state of the record. If this is not available from the connection (often the case on N-tier apps where the user is not being impersonated at the database level) then you need to find some other way to get it.