SQL SERVER – 2005 – Server and Database Level DDL Triggers Examples and Explanation

SQL SERVER - 2005 - Server and Database Level DDL Triggers Examples and Explanation trigger1 I was asked following questions when discussing security issues in meeting with offshore team of large database consultancy company few days ago. I will only discuss one of the security issue was discussed accidental data modification by developers and DBAs themselves. Let’s learn about Server and Database Level DDL Triggers Examples and Explanation here.

How to alter modification in database by system admin himself?

How to prevent accidents due to fat fingers? (Accidental execution of code)

How to display message to contact another developer when another developer tries to modify object another developer working on?

It was an interesting conversation. The answer to all the questions is the correct assignment of permissions and (when permissions are not an issue) Server and Database Level DDL Triggers. If developers have their own login to SQL Server and it does not have permissions to drop or create objects this will not be issued at all. However, there is still a risk of System Admin himself making accidental mistakes. The solution to this will be use Server and Database Level DDL Triggers.

DDL is abbreviation of Data Definition Level. DDL contains the schema of the database object. It was always dreaming of all DBA, when a change in the mission critical schema of the database or server is attempted it is prevented immediately informing DBA and users automatically. DDL Trigger can now make this dream true. Definition of DDL Trigger (from BOL) is DDL Triggers are a special kind of trigger that fire in response to Data Definition Language (DDL) statements. They can be used to perform administrative tasks in the database such as auditing and regulating database operations.

DML is abbreviation of Data Manipulation Level. DML contains the actual data which is stored in the database schema. UPDATE, INSERT, DELETE, SELECT is clause are used to manipulate database. There is following a different between DML and DDL triggers.

  • DDL triggers do not support INSTEAD OF feature DML triggers.
  • DDL triggers do not have a feature of inserted and deleted tables like DML triggers as it does not participate in database manipulations.

Following example demonstrates how DDL trigger can be used to prevent dropping stored procedure.

DDL Trigger

Step 1 :

First, create any sample stored procedure.

USE AdventureWorks; 
GO 
CREATE PROCEDURE TestSP 
AS 
SELECT 1 test; 
GO 

Step 2 :

Create DDL trigger which will prevent dropping the stored procedure.

USE AdventureWorks 
GO 
CREATE TRIGGER PreventDropSP 
ON DATABASE  
FOR DROP_PROCEDURE 
AS
PRINT 'Dropping Procedure is not allowed. DDL Trigger
is preventing this from happening.
To drop stored procedure run following script. 
Script : DISABLE TRIGGER PreventDropSP ON DATABASE;
<Run your DROP SP> ENABLE TRIGGER PreventDropSP ON DATABASE;' 
ROLLBACK; 
GO 

Step 3 :

Now test above trigger by attempting to drop the stored procedure.

USE AdventureWorks 
GO 
DROP PROCEDURE TestSP; 
GO 

This should throw following message along with error code 3609 :

Dropping Procedure is not allowed.

DDL Trigger is preventing this from happening.

To drop stored procedure run following script.

Script:


DISABLE TRIGGER PreventDropSP ON DATABASE;

<Run your DROP SP>;

ENABLE TRIGGER PreventDropSP ON DATABASE;

Msg 3609, Level 16, State 2, Line 1

The transaction ended in the trigger. The batch has been aborted.

Step 4 :

Now DISABLE above trigger and it will let you successfully drop the stored procedure previously attempted to drop. Once it is dropped enable trigger again to prevent future accidents.

USE AdventureWorks 
GO 
DISABLE TRIGGER PreventDropSP ON DATABASE;
DROP PROCEDURE TestSP;
ENABLE TRIGGER PreventDropSP ON DATABASE; 
GO  

List of all the DDL events (DROP_PROCEDURE in the example above) to use with DDL Trigger are listed on MSDN.

If you want to download local copycopy, click here.

Reference : Pinal Dave (http://www.SQLAuthority.com), BOL

, , ,
Previous Post
SQL SERVER – UDF – Get the Day of the Week Function
Next Post
SQL SERVER – Data Warehousing Interview Questions and Answers – Introduction

Related Posts

50 Comments. Leave new

  • DDL actually stands for Data Definition Language not Level. Sorry to be nit-picky, just wanted to clarify.

    Reply
  • Hey Pinal!
    I posted a comment on this entry yesterday and today it’s gone.
    Did I do something wrong?

    Reply
  • Hi Phillip,

    I am not sure I receive more than 200 comments and 1000 of spams. I do not read any spams and delete them right away. Your comment can be categorized incorrectly.

    However, when you post comment, you can immediately see them till it is approved by spam filter.

    What is the comment about?

    Kind Regards,
    Pinal

    Reply
  • Paul Nielsen has written a stored procedure that creates audit triggers for every table in your database.
    Check out AutoAudit at

    Reply
  • can i dynamically generate the ddl for all of the sqlserver 2005 databases on the server, using a script.

    thanks

    Reply
  • How do you check the status of the trigger?

    I wanted to know the trigger is enabled or disabled?

    Reply
  • Hi Pinal

    Iam new to triggers Sql server 2005.

    Iam want to send a message to a user when data is inserted/updated to a table depending on a criteria. The data is comming from an external program which I ave no control to code. Can we capture the ip address as this is a multi user system. Do you have exapmles that i can use or look at.

    Reply
  • Hi Pinal,
    I have a trigger on a tracker table. Is there anything i can do so that others can not DISABLE that trigger? (In our organization, few S/W developers have access to DB). Or atleast, any way so that I can track the Enabling/Disabling that trigger ?

    Thanks..

    Reply
  • I use this to prevent people from modifying the DDL triggers:

    –disable the trigger to add security exceptions
    DISABLE TRIGGER [dba_trigger_log_db_events] ON DATABASE
    GO

    –get user names on the database
    DECLARE @sqlCmd nvarchar(4000)
    DECLARE curLoginsToDeny CURSOR FOR
    SELECT ‘DENY ALTER ANY DATABASE DDL TRIGGER TO [‘+[name]+’];’ [sqlCmd]
    FROM sys.database_principals
    WHERE [principal_id] > 4 — 0 to 4 are system users/schemas
    and [type] IN (‘G’, ‘S’, ‘U’) –windows group, sql server login, windows user
    and [name] NOT LIKE ”

    OPEN curLoginsToDeny
    FETCH NEXT FROM curLoginsToDeny INTO @sqlCmd
    WHILE @@FETCH_STATUS = 0 –successful fetch
    BEGIN
    EXEC sp_executesql @sqlCmd –execute command to revoke rights
    FETCH NEXT FROM curLoginsToDeny INTO @sqlCmd
    END
    CLOSE curLoginsToDeny
    DEALLOCATE curLoginsToDeny
    GO

    –ENABLE the trigger after security exceptions are applied
    ENABLE TRIGGER [dba_trigger_log_db_events] ON DATABASE
    GO

    This works well even for people who are DBO on the database. I also recommend using the WITH ENCRYPTION option:

    CREATE TRIGGER [dba_trigger_log_db_events]
    ON DATABASE
    WITH ENCRYPTION

    Hope that helps!

    Reply
  • Thanks a lot Steve..

    Reply
  • Hi Pinal,

    How can I make a Trigger that fires at 7:00 am every morning and excecutes a Stored procedure?
    Do I need to make a Job for it or is there a better alternative?

    Reply
    • That’s not the function of a trigger. You’d be best setting up a SQL Server Agent job for this purpose.

      Reply
  • Hi Megha,

    You can not fire trigger as you execute Stored Procedure. Trigger will be automatically fire when INSERT/UPDATE/DELETE command executing on the table.

    To execute Stored Procedure, you have to create JOB to run at that specific time.

    Thanks,

    Tejas

    Reply
  • There is a database in a folder in C drive. when the folder exceeds 1MB A trigger is fired which transfer all these data into another folder in D drive. can anyone help me in this

    Reply
  • I need to create a basic ddl trigger that notifies on database creates, drops and alters. Nothing fancy because these databases are in a highly secure “nitch” – no database mail, not even a good way to get the results from one spot to another. I just need the info to either go to the default location, or a flat file. Don’t need to prevent. So far I’ve found this very easily:

    CREATE TRIGGER tr_tableChange
    ON DATABASE
    FOR CREATE_TABLE, DROP_TABLE, ALTER_TABLE
    AS
    BEGIN
    do some activity based on event
    END

    Is there a default, basic setup that logs to sys.events? This seems like it should be a lot simpler. :)

    Reply
  • Imran Mohammed
    July 16, 2009 8:51 am

    @russoaks

    If you want something easy, then you can use osql commands to generate a text file on OS, When ever this trigger fires.

    You will find plenty of examples for osql ( export or creating text file on OS)

    If you need help, just leave a comment. Will be glad to help you out.

    ~ IM

    Reply
  • Hi, I want to know how to execute local temporery procedure with example.. anyone help me..

    Reply
  • Hi, your explanation is excellent.
    In step 2, you provided details for security while droping the stored procedure.

    Don’t we have security in tables also?

    Reply
  • Srinivas Donavalli
    November 17, 2009 10:56 am

    Pinal,
    Since long time I am observing your blogs and your posts. First I appreciate your efforts to spend your valuable time nad made technology easier even for basic level developer.

    Now come to the point, some where in this blog I have seen about cursors. In this you said cursor is a database object. I did lot of research how it become an object with out mangaing by dbms. If we see the execution engine of the SQL stateemnt i didnt see SQl is treating it as a object. Even microsoft also saying it as datatype.

    For your reference:
    https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2005/ms190498(v=sql.90)

    If you provide your explanation that would be great.

    I want to know one more thing. I am expecting some quick replys from you. Is there any way to post query for different area like that.
    Ex: For SQL joins do i need to post in only SQL joins area ?

    Thanks,
    Srinivas Donavalli.

    Reply
  • Is it possible to see all the triggers from information_schema

    Reply
  • how to create a trigger to stop insert,update,detele commnds

    Reply

Leave a Reply