Counter of Festivals

Ashok Blog for SQL Learners and Beginners and Experts

Thursday 29 November 2012

Different Types of SQL Server Triggers and Explanations


Triggers are database object. Basically these are special type of stored procedure that are automatically fired/executed when a DDL or DML command statement related with the trigger is executed. Triggers are used to assess/evaluate data before or after data modification using DDL and DML statements. These are also used to preserve data integrity, to control server operations, to audit a server and to implement business logic or business rule.

Types of Triggers

In Sql Server we can create four types of triggers Data Definition Language (DDL) triggers, Data Manipulation Language (DML) triggers, CLR triggers and Logon triggers.
  1. DDL Triggers

    In SQL Server we can create triggers on DDL statements (like CREATE, ALTER, and DROP) and certain system defined stored procedures that perform DDL-like operations.
    Example : If you are going to execute the CREATE LOGIN statement or the sp_addlogin stored procedure to create login user, then both these can execute/fire a DDL trigger that you can create on CREATE_LOGIN event of Sql Server.
    We can use only FOR/AFTER clause in DDL triggers not INSTEAD OF clause means we can make only After Trigger on DDL statements.
    DDL trigger can be used to observe and control actions performed on the server, and to audit these operations. DDL triggers can be used to manage administrator tasks such as auditing and regulating database operations.
  2. DML Triggers

    In SQL Server we can create triggers on DML statements (like INSERT, UPDATE, and DELETE) and stored procedures that perform DML-like operations. DML Triggers are of two types
    1. After Trigger (using FOR/AFTER CLAUSE)

      This type of trigger fires after SQL Server finish the execution of the action successfully that fired it.
      Example : If you insert record/row in a table then the trigger related/associated with the insert event on this table will fire only after the row passes all the constraints, like as primary key constraint, and some rules. If the record/row insertion fails, SQL Server will not fire the After Trigger.
    2. Instead of Trigger (using INSTEAD OF CLAUSE)

      This type of trigger fires before SQL Server starts the execution of the action that fired it. This is differ from the AFTER trigger, which fires after the action that caused it to fire. We can have an INSTEAD OF insert/update/delete trigger on a table that successfully executed but does not include the actual insert/update/delete to the table.
      Example : If you insert record/row in a table then the trigger related/associated with the insert event on this table will fire before the row passes all the constraints, such as primary key constraint and some rules. If the record/row insertion fails, SQL Server will fire the Instead of Trigger.
  3. CLR Triggers

    CLR triggers are special type of triggers that based on the CLR (Common Language Runtime) in .net framework. CLR integration of triggers has been introduced with SQL Server 2008 and allows for triggers to be coded in one of .NET languages like C#, Visual Basic and F#.
    We coded the objects(like trigger) in the CLR that have heavy computations or need references to objects outside the SQL Server. We can write code for both DDL and DML triggers, using a supported CLR language like C#, Visual basic and F#. I will discuss CLR trigger later.
  4. Logon Triggers

    Logon triggers are special type of trigger that fire when LOGON event of Sql Server is raised. This event is raised when a user session is being established with Sql Server that is made after the authentication phase finishes, but before the user session is actually established. Hence, all messages that we define in the trigger such as error messages, will be redirected to the SQL Server error log. Logon triggers do not fire if authentication fails. We can use these triggers to audit and control server sessions, such as to track login activity or limit the number of sessions for a specific login.
    Synatx for Logon Trigger
    1. CREATE TRIGGER trigger_name
    2. ON ALL SERVER
    3. [WITH ENCRYPTION]
    4. {FOR|AFTER} LOGON
    5. AS
    6. sql_statement [1...n ]


    Syntax for Trigger

    1. CREATE TRIGGER trigger_name
    2. ON {table|view}
    3. [WITH ENCRYPTION|EXECUTE AS]
    4. {FOR|AFTER|INSTEAD OF} {[CREATE|ALTER|DROP|INSERT|UPDATE|DELETE ]}
    5. [NOT FOR REPLICATION]
    6. AS
    7. sql_statement [1...n ]
    1. trigger_name

      This is the name of the trigger. It should conform to the rules for identifiers in Sql Server.
    2. table|view

      This is the table/view on which the trigger is to be created.
    3. ENCRYPTION

      This option is optional. If this option is specified, original text of the CREATE TRIGGER statement will be encrypted.
    4. EXECUTE AS

      This option is optional. This option specifies, the security context under which the trigger is executed.
    5. FOR/AFTER

      FOR/AFTER specifies that the trigger is After Trigger. AFTER is the default, if FOR is the only keyword specified.AFTER triggers cannot be defined on views.
    6. INSTEAD OF

      INSTEAD OF specifies that the trigger is Instead Of Trigger.
    7. CREATE|ALTER|DROP|INSERT|UPDATE|DELETE

      These keywords specify on which action the trigger should be fired. One of these keywords or any combination of these keywords in any order can be used.
    8. NOT FOR REPLICATION

      Indicates that the trigger should not be executed when a replication process modifies the table involved in the trigger.
    9. AS

      After this we specifies the actions and condition that the trigger perform.
    10. sql_statement

      These are the trigger conditions and actions. The trigger actions specified in the T-SQL statements.

      Note

      1. The name of a trigger should follow the rules for identifiers.
      2. DML trigger can be composed by any T-SQL statements, except CREATE DATABASE, ALTER DATABASE, DROP DATABASE, LOAD DATABASE, LOAD LOG, RECONFIGURE, RESTORE DATABASE, and RESTORE LOG statements.
      3. You cannot create triggers against system tables or dynamic management views. Moreover, the TRUNCATE TABLE statement does not fire a trigger because this operation does not log individual row deletions.
      4. If you use the DATABASE option, the scope of your DDL trigger will be the current database. If you use the ALL SERVER option, the scope of your DDL triggers to the current server.
      5. AFTER triggers cannot be defined on views.
      6. AFTER is the default, if FOR is the only keyword specified


        Triggers are special type of stored procedure that automatically execute when a DDL or DML statement associated with the trigger is executed. DML Triggers are used to evaluate data after data manipulation using DML statements. We have two types of DML triggers.

        Types of DML Triggers

        1. After Trigger (using FOR/AFTER CLAUSE)

          This trigger fires after SQL Server completes the execution of the action successfully that fired it.
          Example :If you insert record/row in a table then the trigger associated with the insert event on this table will fire only after the row passes all the checks, such as primary key, rules, and constraints. If the record/row insertion fails, SQL Server will not fire the After Trigger.
        2. Instead of Trigger (using INSTEAD OF CLAUSE)

          This trigger fires before SQL Server starts the execution of the action that fired it. This is much more different from the AFTER trigger, which fires after the action that caused it to fire. We can have an INSTEAD OF insert/update/delete trigger on a table that successfully executed but does not include the actual insert/update/delet to the table.
          Example :If you insert record/row in a table then the trigger associated with the insert event on this table will fire before the row passes all the checks, such as primary key, rules, and constraints. If the record/row insertion fails, SQL Server will fire the Instead of Trigger.

        Example

        1. -- First create table Employee_Demo
        2. CREATE TABLE Employee_Demo
        3. (
        4. Emp_ID int identity,
        5. Emp_Name varchar(55),
        6. Emp_Sal decimal (10,2)
        7. )
        8. -- Now Insert records
        9. Insert into Employee_Demo values ('Amit',1000);
        10. Insert into Employee_Demo values ('Mohan',1200);
        11. Insert into Employee_Demo values ('Avin',1100);
        12. Insert into Employee_Demo values ('Manoj',1300);
        13. Insert into Employee_Demo values ('Riyaz',1400);
        14. --Now create table Employee_Demo_Audit for logging/backup purpose of table Employee_Demo create table Employee_Demo_Audit
        15. (
        16. Emp_ID int,
        17. Emp_Name varchar(55),
        18. Emp_Sal decimal(10,2),
        19. Audit_Action varchar(100),
        20. Audit_Timestamp datetime
        21. )
        Now I am going to explain the use of After Trigger using Insert, Update, Delete statement with example
        1. After Insert Trigger

          1. -- Create trigger on table Employee_Demo for Insert statement
          2. CREATE TRIGGER trgAfterInsert on Employee_Demo
          3. FOR INSERT
          4. AS declare @empid int, @empname varchar(55), @empsal decimal(10,2), @audit_action varchar(100);
          5. select @empid=i.Emp_ID from inserted i;
          6. select @empname=i.Emp_Name from inserted i;
          7. select @empsal=i.Emp_Sal from inserted i;
          8. set @audit_action='Inserted Record -- After Insert Trigger.'; insert into Employee_Demo_Audit(Emp_ID,Emp_Name,Emp_Sal,Audit_Action,Audit_Timestamp)
          9. values (@empid,@empname,@empsal,@audit_action,getdate());
          10. PRINT 'AFTER INSERT trigger fired.'
          11. --Output will be
          1. --Now try to insert data in Employee_Demo table
          2. insert into Employee_Demo(Emp_Name,Emp_Sal)values ('Shailu',1000);
          3. --Output will be
          1. --now select data from both the tables to see trigger action
          2. select * from Employee_Demo
          3. select * from Employee_Demo_Audit
          4. --Output will be
          Trigger have inserted the new record to Employee_Demo_Audit table for insert statement. In this way we can trace a insert activity on a table using trigger.
        2. After Update Trigger

          1. -- Create trigger on table Employee_Demo for Update statement
          2. CREATE TRIGGER trgAfterUpdate ON dbo.Employee_Demo
          3. FOR UPDATE
          4. AS
          5. declare @empid int, @empname varchar(55), @empsal decimal(10,2), @audit_action varchar(100);
          6. select @empid=i.Emp_ID from inserted i;
          7. select @empname=i.Emp_Name from inserted i;
          8. select @empsal=i.Emp_Sal from inserted i; if update(Emp_Name)
          9. set @audit_action='Update Record --- After Update Trigger.';
          10. if update (Emp_Sal)
          11. set @audit_action='Update Record --- After Update Trigger.';
          12. insert intoEmployee_Demo_Audit(Emp_ID,Emp_Name,Emp_Sal,Audit_Action,Audit_Timestamp)
          13. values (@empid,@empname,@empsal,@audit_action,getdate());
          14. PRINT 'AFTER UPDATE trigger fired.'
          15. --Output will be
          1. --Now try to upadte data in Employee_Demo table
          2. update Employee_Demo set Emp_Name='Pawan' Where Emp_ID =6;
          3. --Output will be
          1. --now select data from both the tables to see trigger action
          2. select * from Employee_Demo
          3. select * from Employee_Demo_Audit
          4. --Output will be
          Trigger have inserted the new record to Employee_Demo_Audit table for update statement. In this way we can trace a update activity on a table using trigger.
        3. After Delete Trigger

          1. -- Create trigger on table Employee_Demo for Delete statement
          2. CREATE TRIGGER trgAfterDelete ON dbo.Employee_Demo
          3. FOR DELETE
          4. AS
          5. declare @empid int, @empname varchar(55), @empsal decimal(10,2), @audit_action varchar(100); select @empid=d.Emp_ID FROM deleted d;
          6. select @empname=d.Emp_Name from deleted d;
          7. select @empsal=d.Emp_Sal from deleted d;
          8. select @audit_action='Deleted -- After Delete Trigger.';
          9. insert into Employee_Demo_Audit (Emp_ID,Emp_Name,Emp_Sal,Audit_Action,Audit_Timestamp)
          10. values (@empid,@empname,@empsal,@audit_action,getdate());
          11. PRINT 'AFTER DELETE TRIGGER fired.'
          12. --Output will be
          1. --Now try to delete data in Employee_Demo table
          2. DELETE FROM Employee_Demo where emp_id = 5
          3. --Output will be
          1. --now select data from both the tables to see trigger action
          2. select * from Employee_Demo
          3. select * from Employee_Demo_Audit
          4. --Output will be
          Trigger have inserted the new record to Employee_Demo_Audit table for delete statement. In this way we can trace a delete activity on a table using trigger.
        Now I am going to explain the use of Instead of Trigger using Insert, Update, Delete statement with example
        1. Instead of Insert Trigger

          1. -- Create trigger on table Employee_Demo for Insert statement
          2. CREATE TRIGGER trgInsteadOfInsert ON dbo.Employee_Demo
          3. INSTEAD OF Insert
          4. AS
          5. declare @emp_id int, @emp_name varchar(55), @emp_sal decimal(10,2), @audit_action varchar(100);
          6. select @emp_id=i.Emp_ID from inserted i;
          7. select @emp_name=i.Emp_Name from inserted i;
          8. select @emp_sal=i.Emp_Sal from inserted i;
          9. SET @audit_action='Inserted Record -- Instead Of Insert Trigger.';
          10. BEGIN
          11. BEGIN TRAN
          12. SET NOCOUNT ON
          13. if(@emp_sal>=1000)
          14. begin
          15. RAISERROR('Cannot Insert where salary < 1000',16,1); ROLLBACK; end
          16. else begin Insert into Employee_Demo (Emp_Name,Emp_Sal) values (@emp_name,@emp_sal); Insert into Employee_Demo_Audit(Emp_ID,Emp_Name,Emp_Sal,Audit_Action,Audit_Timestamp) values(@@identity,@emp_name,@emp_sal,@audit_action,getdate());
          17. COMMIT;
          18. PRINT 'Record Inserted -- Instead Of Insert Trigger.'
          19. END
          20. --Output will be
          1. --Now try to insert data in Employee_Demo table
          2. insert into Employee_Demo values ('Shailu',1300)
          3. insert into Employee_Demo values ('Shailu',900) -- It will raise error since we are checking salary >=1000
          4. --Outputs will be
           
          1. --now select data from both the tables to see trigger action
          2. select * from Employee_Demo
          3. select * from Employee_Demo_Audit
          4. --Output will be
          Trigger have inserted the new record to Employee_Demo_Audit table for insert statement. In this way we can apply business validation on the data to be inserted using Instead of trigger and can also trace a insert activity on a table.
        2. Instead of Update Trigger

          1. -- Create trigger on table Employee_Demo for Update statement
          2. CREATE TRIGGER trgInsteadOfUpdate ON dbo.Employee_Demo
          3. INSTEAD OF Update
          4. AS
          5. declare @emp_id int, @emp_name varchar(55), @emp_sal decimal(10,2), @audit_action varchar(100);
          6. select @emp_id=i.Emp_ID from inserted i;
          7. select @emp_name=i.Emp_Name from inserted i;
          8. select @emp_sal=i.Emp_Sal from inserted i;
          9. BEGIN
          10. BEGIN TRAN
          11. if(@emp_sal>=1000)
          12. begin
          13. RAISERROR('Cannot Insert where salary < 1000',16,1); ROLLBACK; end
          14. else begin
          15. insert into Employee_Demo_Audit(Emp_ID,Emp_Name,Emp_Sal,Audit_Action,Audit_Timestamp) values(@emp_id,@emp_name,@emp_sal,@audit_action,getdate());
          16. COMMIT;
          17. PRINT 'Record Updated -- Instead Of Update Trigger.'; END
          18. --Output will be
          1. --Now try to upadte data in Employee_Demo table
          2. update Employee_Demo set Emp_Sal = '1400' where emp_id = 6
          3. update Employee_Demo set Emp_Sal = '900' where emp_id = 6
          4. --Output will be
           
          1. --now select data from both the tables to see trigger action
          2. select * from Employee_Demo
          3. select * from Employee_Demo_Audit
          4. --Output will be
          Trigger have inserted the updated record to Employee_Demo_Audit table for update statement. In this way we can apply business validation on the data to be updated using Instead of trigger and can also trace a update activity on a table.
        3. Instead of Delete Trigger

          1. -- Create trigger on table Employee_Demo for Delete statement
          2. CREATE TRIGGER trgAfterDelete ON dbo.Employee_Demo
          3. INSTEAD OF DELETE
          4. AS
          5. declare @empid int, @empname varchar(55), @empsal decimal(10,2), @audit_action varchar(100); select @empid=d.Emp_ID FROM deleted d;
          6. select @empname=d.Emp_Name from deleted d;
          7. select @empsal=d.Emp_Sal from deleted d;
          8. BEGIN TRAN if(@empsal>1200) begin
          9. RAISERROR('Cannot delete where salary > 1200',16,1);
          10. ROLLBACK;
          11. end
          12. else begin
          13. delete from Employee_Demo where Emp_ID=@empid;
          14. COMMIT;
          15. insert into Employee_Demo_Audit(Emp_ID,Emp_Name,Emp_Sal,Audit_Action,Audit_Timestamp)
          16. values(@empid,@empname,@empsal,'Deleted -- Instead Of Delete Trigger.',getdate());
          17. PRINT 'Record Deleted -- Instead Of Delete Trigger.' end END
          18. --Output will be
          1. --Now try to delete data in Employee_Demo table
          2. DELETE FROM Employee_Demo where emp_id = 1
          3. DELETE FROM Employee_Demo where emp_id = 3
          4. --Output will be
           
          1. --now select data from both the tables to see trigger action
          2. select * from Employee_Demo
          3. select * from Employee_Demo_Audit
          4. --Output will be
          Trigger have inserted the deleted record to Employee_Demo_Audit table for delete statement. In this way we can apply business validation on the data to be deleted using Instead of trigger and can also trace a delete activity on a table.