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

I was asked following questions when discussing security issues in meeting with off-shore 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.

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 developers when another developer tries to modify object another developer working on?

It was interesting conversation. Answer to all the questions is 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 issue at all. However, there are still 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 schema of the database object. It was always dream of all DBA, when change in 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 are clause are used to manipulate database. There is following different between DML and DDL triggers.

  • DDL triggers do not support INSTEAD OF feature DML triggers.
  • DDL triggers do not have 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.

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 example above) to use with DDL Trigger are listed on MSDN.

If you want to download local copy click here.

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

About these ads

51 thoughts on “SQL SERVER – 2005 – Server and Database Level DDL Triggers Examples and Explanation

  1. 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

  2. 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.

  3. 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..

  4. 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!

  5. Pingback: SQL SERVER - 2008 - Interview Questions and Answers - Part 1 Journey to SQL Authority with Pinal Dave

  6. 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?

  7. 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

  8. 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

  9. 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. :)

  10. @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

  11. 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?

  12. 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:
    http://msdn.microsoft.com/en-us/library/ms190498(SQL.90).aspx

    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.

  13. Dear Sir i am using below code in Sql2005 and getting error . Please help me.
    USE Test

    GO

    CREATE TRIGGER PreventDropSP

    ON Test

    FOR DROP_PROCEDURE

    AS

    PRINT ‘Dropping Procedure is not allowed.’

    ROLLBACK;

    GO

    “””Msg 170, Level 15, State 1, Procedure PreventDropSP, Line 6
    Line 6: Incorrect syntax near ‘DROP_PROCEDURE’.””””””

    • hai ved,

      use test
      go

      create trigger preventdropsp

      on database

      for drop_procedure

      as

      print PRINT ‘Dropping Procedure is not allowed.’

      ROLLBACK;

      GO

      Regards
      kalyan

  14. Hello Ved,

    Write this as following:

    CREATE TRIGGER PreventDropSP
    ON DATABASE
    FOR DROP_PROCEDURE
    AS
    PRINT ‘Dropping Procedure is not allowed.’
    ROLLBACK;
    GO

    Regards,
    Pinal Dave

    • Dear Sir

      Thanks for your reply .However i am getting same error ..

      Can you please give me any one of DDL Trigger Example.

      Thanks
      Ved

  15. Hello,

    I wish to track when anyone does INSERT,UPDATE, DELETE on any of the tables in a database. Is it possible to write database level trigger for this case?

    Thanks,
    -Saroj

  16. hi sir i m creating trigger as
    create trigger check_id
    ON dbo.teacher
    AFTER INSERT,UPDATE
    AS
    BEGIN
    SET NOCOUNT ON;
    IF(t_no<100)
    THEN
    print('not allowed');
    END;
    but getting an error
    Msg 156, Level 15, State 1, Procedure check_id, Line 8
    Incorrect syntax near the keyword 'THEN'
    pls. help me as ma a beginner in sql .

    • Hi,
      There is an syntax error in the IF. check this out.
      create trigger check_id
      ON dbo.interest_rate
      AFTER INSERT,UPDATE
      AS
      BEGIN
      SET NOCOUNT ON;
      IF(select Interest_rate from inserted) <100
      print('not allowed')
      END

  17. Help Plz..

    Well hello there.. i am facing problem in updating using trigger

    following the trigger..

    well my requirements is to update the column . I want to store(update) the prev. value while updating in another columns correspond to id.

    like prevsal and newsalary.

    following trigger which i have created…

    *as we know when we update then (inserted and deleted will fire also in which the old value which we can retrieve using (select * from deleted))

    ALTER trigger [dbo].[tb] on [dbo].[tb_name]
    for insert, update
    as

    declare @count int

    declare @loop int

    declare @empid int

    select @loop =1

    select @count = (select * from tblname)

    WHILE(@loop <= @count)

    update tblname set newsalary=1200 where id=@loop and date='12/12/2010'

    set @loop= @loop+1

    update tblname set prevsal=(select newsalary from deleted)

    End

    *if there any Error then let me know well i am updating the field with column name newsalary but for column name prevsal they givng me NULL value except old value..

    hope you can understand my requirement

    with regards

    vikram

  18. Pingback: SQL SERVER – Interview Questions and Answers – Frequently Asked Questions – Day 3 of 31 Journey to SQLAuthority

  19. Hi Phillip,

    I am trying to create a simple DDL trigger on server level, everything is fine on my local machine but when I am trying on our server (SQL 2005 Clustered) I am getting Error, any idea?

    Create TRIGGER test
    ON ALL SERVER
    FOR DDL_DATABASE_LEVEL_EVENTS
    AS
    BEGIN
    print ‘Hello’
    END

    Msg 1098, Level 15, State 1, Procedure test, Line 7
    The specified event type(s) is/are not valid on the specified target object.

  20. i want to execute the trigger whenever the new login is created i.e. new entry added to master..syslogins table ,

    Which server trigger i need to have and whats the synatx and minimum permissions needed to create it , now i am security admin.

  21. Pingback: SQL SERVER – Significance of Various Kinds of Triggers- Quiz – Puzzle – 2 of 31 « SQL Server Journey with SQL Authority

  22. Hello.
    Is it possible to create a trigger to insert, update and delete data from all tables of current database?

    Something like this:

    CREATE TRIGGER myTrigger
    ON
    FOR INSERT, UPDATE, DELETE
    AS IF (@@ERROR 0)
    BEGIN
    INSERT into #tableSomething VALUES (1)
    END

    I’m using SQL Server 2008.
    Thank you
    TAP

  23. I m working on Trigger which will prevent database users from executing update statement on table.
    Sir, I Want to hide error 3609 after execution of Trigger.

  24. while trying to drop stored procs, error:

    Dropping Procedure is not allowed. DDL Trigger is preventing this from happening. To drop stored procedure run following script.

    Kindly help me….

  25. I m beginner in triggers i got this error..
    plz help me..

    thank u..

    CREATE TRIGGER preventDB
    ON DATABASE
    FOR DROP_PROCEDURE
    AS
    PRINT ‘HELLO’
    ROLLBACK
    GO

    error is…
    Incorrect syntax near the keyword ‘DATABASE’.

  26. Dear Pinal Dave,

    Where this magic tables are created?
    When they will created?
    When they will dropped?
    How long it will be used?

    Thanks,
    Prakash.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s