Take the 2-minute tour ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

My department works on converting a client's database when a client switches from another company to us. We have a RDP session they can connect to and see our software with their data. Once they approve the conversion we copy the data from our server and set it up on site for them.

During the conversion approval phase it would make things a lot simpler for us if we could have some AFTER and INSTEAD OF triggers be running on all databases attached to the server (Our department is a different department than the one that develops the software and they will not make a version for the testing site that does the stuff for us built in for us).

I see two options:

  1. Create a DML trigger that either performs the action on all databases attached to the server, but when the database is moved to the live server the action no longer occurs because it is run on the server not the database.
  2. Have a DML trigger that deletes itself if it detects that it is no longer attached to the test server and is in a live environment.

From what I read I don't think the first option is possible, but I wanted to check and see. I think I know enough to do the 2nd option, but any examples of how to implement it would be very helpful.

share|improve this question

2 Answers 2

up vote 2 down vote accepted

You are not going to be able to create a server-wide trigger, because it has to exist in the same database that the DML changes are occurring in.

Having self-deleting code sounds a bit problematic as well.

I think you are going to have to have a process in place that creates the triggers when a new database is attached, and removes them when you are finished with them. This is likely going to be a manual process.

share|improve this answer
    
The only concern is if other people get the data from the server they may not follow the correct procedure and we don't want a case of the triggers being accidentally left on in a production environment. –  Scott Chamberlain May 2 '12 at 15:57

In the following example, information about the event that fired the trigger is captured using the SQL Server’s EVENTDATA() function. The SQL script creates DDL trigger that captures CREATE, ALTER, and DROP events on a database level (although, triggers can be created on the server level to capture events for all databases on the server; ON ALL SERVER option should be used, instead of ON DATABASE):

CREATE TRIGGER Audit_DDL
ON DATABASE
    FOR CREATE_TABLE, ALTER_TABLE, DROP_TABLE
AS
     DECLARE
        @event xml;
     SET
     @event = EVENTDATA();
     INSERT INTO Audit_DDL_Events
     VALUES
     (
     REPLACE(CONVERT(varchar(50),
     @event.query('data(/EVENT_INSTANCE/PostTime)')), 'T', ' ')
     ,
     CONVERT(varchar(150),
     @event.query('data(/EVENT_INSTANCE/LoginName)'))
     ,
     CONVERT(varchar(150),
     @event.query('data(/EVENT_INSTANCE/UserName)'))
     ,
     CONVERT(varchar(150),
     @event.query('data(/EVENT_INSTANCE/DatabaseName)'))
     ,
     CONVERT(varchar(150),
     @event.query('data(/EVENT_INSTANCE/SchemaName)'))
     ,
     CONVERT(varchar(150),
     @event.query('data(/EVENT_INSTANCE/ObjectName)'))
     ,
     CONVERT(varchar(150),
     @event.query('data(/EVENT_INSTANCE/ObjectType)'))
     ,
     CONVERT(varchar(max),
     @event.query('data(/EVENT_INSTANCE/TSQLCommand/CommandText)'))
     );

An appropriate storage table for the auditing data from EVENTDATA XML must be created also:

CREATE TABLE Audit_DDL_Events
(
             DDL_Event_Time            datetime
             ,
             DDL_Login_Name            varchar(150)
             ,
             DDL_User_Name             varchar(150)
             ,
             DDL_Database_Name         varchar(150)
             ,
             DDL_Schema_Name           varchar(150)
             ,
             DDL_Object_Name           varchar(150)
             ,
             DDL_Object_Type           varchar(150)
             ,
             DDL_Command              varchar(max)
);

Now, that we’ve set the stage for tracking DDL changes, the information in case of creating, modifying, or deleting a table captured via triggers would look like:

enter image description here

Although we’ve shown that this method can produce viable auditing results, tracking DDL changes in SQL Server using triggers has several disadvantages. First of all, a user with sufficient permissions can easily disable the triggers. Another way to avoid tracking DDL changes in SQL Server by triggers is to perform a schema change and then delete captured information from auditing repository. In our case, simply by deleting an appropriate entry from the Audit_DDL_Events table. Moreover, if no privileged users who can maliciously perform DDL changes exists, this method cannot provide information about changes that took place before it was set up

You can read more about the topic in the Tracking DDL changes in SQL Server – the ‘Trouble with Triggers’ online article

Disclaimer: I work as a Product Support Engineer at ApexSQL

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.