After Trigger vs Instead of Trigger in SQL Server

This article explains the After Trigger and Instead of Trigger using an example and the differences between them.

This article explains the "After Trigger" and "Instead of Trigger" using an example and the differences between them but first you need to look at an overview of both.

After Trigger: These kinds of triggers fire after the execution of an action query that can be either DDL statements like Create, Alter and Drop or DML statements like Insert, Update and Delete.

Instead of Trigger: These kinds of triggers fire before the execution of an action query that can only be DML statements like Insert, Update and Delete but after the execution of that query. The table data will not be affected, in other words if you want to insert or update the data of the table then you need to write it in the trigger using "inserted" or "deleted" virtual tables.

Syntax of Trigger

  1. CREATE TRIGGER trigger_name ON {table|view}  
  2. [WITH ENCRYPTION|EXECUTE AS]  
  3. {FOR|AFTER|INSTEAD OF} {[CREATE|ALTER|DROP|INSERT|UPDATE|DELETE ]}  
  4. [NOT FOR REPLICATION]  
  5. AS  
  6. sql_statement [1...n ] 
Use the following procedure to understand the differences between them.

Step 1: Create a schema of a table named "Employee" in the database for performiing an action such as insert.

  1. create table Employee  
  2. (  
  3. ID int primary key,  
  4. Name varchar(20),  
  5. Salary float,  
  6. Department varchar(20)  
  7. )

Employee Table

Step 2: Create a schema table named "Logs" that will contain the activity of the trigger.

  1. create table Logs  
  2. (  
  3. Activity varchar(20),  
  4. Activity_date datetime  
  5. )
Note: I am using SQL Server 2008 in this Demo.

Differences

1. Action Query: In the "After Trigger" the table data is affected after the execution of the action query whereas the table data isn’t affected after the execution of an action query in an "Instead of Trigger".

Examples

After Trigger: I create an After Trigger that executes an insertion in the "Logs" table when we insert the data in the "Employee" table. Check below for the details.

a. Create a Trigger where, at the time of insertion in the "Employee" table, we insert a record in the "Logs" table.

  1. CREATE TRIGGER trigger_example ON Employee  
  2. AFTER INSERT  
  3. AS  
  4. Insert into Logs values('Data is inserted',getdate())
Logs table 

b. Insert the data in the "Employee" table that executes a trigger automatically and selects both tables to check the data.

Insert into Employee values(1,'Rahul',20000,'Finance')

  1. select * from Employee  
  2. select * from Logs
Insert the data in the Employee table 

Instead of Trigger: If I alter the preceding After Trigger to be an Instead of Trigger that executes an insertion into the "Logs" table when we fire the insertion query into the "Employee" table then the data will not be inserted into the Employee table. Check below for the details.

a. Alter the preceding trigger such that at the time of insertion into the "Employee" table we insert a record into the "Logs" table.

  1. Alter TRIGGER trigger_example ON Employee  
  2. Instead of INSERT  
  3. AS  
  4. Insert into Logs values('Data is inserted',getdate()) 
Note: I have changed the existing trigger.

Instead of Trigger

b. Insert the data in the "Employee" table that executes the trigger automatically.

Insert into Employee values(2,'Bansal',10000,'IT')

  1. select * from Employee  
  2. select * from Logs 
executes trigger automatically 

As you can see, the data wasn’t inserted into the "Employee" table, that’s why it’s called an Instead of trigger, it does something eles instead of the main thing.

2. Insertion and Update in the Table: In the "After Trigger" the table data can be affected without using the "inserted" or "deleted" table whereas the table data isn’t affected without using an "inserted" or "deleted" table in the "Instead of Trigger".

For example:

After Trigger: As you can see, the data has been inserted into the "Employee" table without using an "inserted' virtual table. When I used an "After Trigger" and if I use "inserted" then it will give a primary key violation error. Check below for the details.

a. Alter the trigger and insert the data via the "inserted" virtual table.

  1. Alter TRIGGER trigger_example ON Employee  
  2. After INSERT  
  3. AS  
  4. begin  
  5. Insert into Employee select * from inserted  
  6. Insert into Logs values('Data is inserted',getdate())  
  7. End
Insertion and Updation in Table 

b. Inserting the new data will generate an error because the action query will fire and wants to insert the data whereas the "inserted" virtual table also wants to insert the same row.

  1. Insert into Employee values(3,'ABC',50000,'IT')  
  2. select * from Employee  
  3. select * from Logs
error 

Instead of Trigger: If I create an instead of trigger using the "inserted" virtual table then the data will be inserted.

a. Alter the trigger and insert the data via the "inserted" virtual table.

  1. Alter TRIGGER trigger_example ON Employee  
  2. Instead of INSERT  
  3. AS  
  4. begin  
  5. Insert into Employee select * from inserted  
  6. Insert into Logs values('Data is inserted',getdate())  
  7. end
Instead of Trigger fire 

b. Insert the data as in the following:

  1. Insert into Employee values(3,'ABC',50000,'IT')  
  2. select * from Employee  
  3. select * from Logs
Insert the data