{"id":47849,"date":"2019-05-15T12:42:44","date_gmt":"2019-05-15T12:42:44","guid":{"rendered":"https:\/\/www.sqlshack.com\/?p=47849"},"modified":"2019-05-15T16:51:45","modified_gmt":"2019-05-15T16:51:45","slug":"triggers-in-sql-server","status":"publish","type":"post","link":"https:\/\/www.sqlshack.com\/triggers-in-sql-server\/","title":{"rendered":"Triggers in SQL Server"},"content":{"rendered":"<p>\n  In this article, we will review triggers in SQL Server, different types of trigger events, trigger order and NOT FOR REPLICATION in triggers. A trigger is a database object that runs automatically when an event occurs. There are three different types of events.\n<\/p>\n<p><!--more--><\/p>\n<ul>\n<li>\n    DML Events\n  <\/li>\n<li>\n    DDL Events\n  <\/li>\n<li>\n    LOGON Event<strong> \u2013 <\/strong>Logon trigger is fired when a LOGON event occurs i.e. when a user session is being established\n  <\/li>\n<\/ul>\n<h2>DML Triggers in SQL Server<\/h2>\n<p>\n  DML triggers in SQL Server are fired when a DML event occurs. i.e. when data is inserted\/ updated\/deleted in the table by a user.\n<\/p>\n<h3>Creating triggers for a DML event<\/h3>\n<p>\n  Let us create some sample tables and triggers in SQL Server.\n<\/p>\n<p><pre lang=\"tsql\">CREATE TABLE Locations (LocationID int, LocName varchar(100))\r\n\r\nCREATE TABLE LocationHist (LocationID int, ModifiedDate DATETIME)<\/pre>\n<\/p>\n<p>\n  We can create a DML trigger for a specific event or multiple events. The triggers in SQL Server(DML) fire on events irrespective to the number of rows affected.\n<\/p>\n<p>\n  Below is the sample syntax for creating a DML trigger for update event.\n<\/p>\n<p><pre lang=\"tsql\">CREATE TRIGGER TR_UPD_Locations ON Locations\r\nFOR UPDATE \r\nNOT FOR REPLICATION \r\nAS\r\n\r\nBEGIN\r\n  INSERT INTO LocationHist\r\n  SELECT LocationID\r\n    ,getdate()\r\n  FROM inserted\r\nEND<\/pre>\n<\/p>\n<p>\n  <img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"550px\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2019\/05\/dml-trigger-for-update-event.png\" alt=\"DML Trigger for UPDATE event\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"550px\" src=\"\/wp-content\/uploads\/2019\/05\/dml-trigger-for-update-event.png\" alt=\"DML Trigger for UPDATE event\" \/><\/noscript>\n<\/p>\n<p>\n  These triggers are created at the table level. Upon successful creation of trigger, we can see the triggers by navigating to <strong>Triggers<\/strong> folder at table level. Please refer to the below image.\n<\/p>\n<p>\n  <img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"350px\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2019\/05\/trigger-on-table.png\" alt=\"Trigger on table\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"350px\" src=\"\/wp-content\/uploads\/2019\/05\/trigger-on-table.png\" alt=\"Trigger on table\" \/><\/noscript>\n<\/p>\n<h3>Instead of triggers in SQL Server<\/h3>\n<p>\n   These triggers are fired before the DML event and the actual data is not modified in the table.\n<\/p>\n<p>\n  For example, if we specify an instead of trigger for delete on a table, when delete statement is issued against the table, the instead of trigger is fired and the T-SQL block inside the triggers in SQL Server is executed but the actual delete does not happen.\n<\/p>\n<p>\n  T-SQL Syntax for creating an instead of trigger\n<\/p>\n<p><pre lang=\"tsql\">CREATE TRIGGER TR_DEL_Locations ON Locations\r\nINSTEAD OF DELETE\r\nAS\r\nBEGIN\r\n  Select 'Sample Instead of trigger' as [Message]\r\nEND<\/pre>\n<\/p>\n<p>\n  <img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"550px\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2019\/05\/instead-of-triggers-in-sql-server.png\" alt=\"INSTEAD OF TRIGGERs in SQL Server\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"550px\" src=\"\/wp-content\/uploads\/2019\/05\/instead-of-triggers-in-sql-server.png\" alt=\"INSTEAD OF TRIGGERs in SQL Server\" \/><\/noscript>\n<\/p>\n<ul>\n<li>\n    If there are multiple triggers along with instead of trigger on the table, the instead of trigger is fired first in the order\n  <\/li>\n<li>\n    INSTEAD of triggers can be created on views\n  <\/li>\n<li>\n    we can define only one instead of trigger per INSERT, UPDATE, or DELETE statement on a table or view\n  <\/li>\n<\/ul>\n<h3>Enabling and disabling DML triggers on a table<\/h3>\n<p>\n  Navigate to triggers folder at the table level, select the trigger, Right click on trigger and Click on <strong>Enable<\/strong>\/<strong>Disable<\/strong> to Enable or disable the trigger using <strong>SSMS<\/strong>.\n<\/p>\n<p>\n  Disabling specific SQL Server trigger on a table using T-SQL.\n<\/p>\n<p><pre lang=\"tsql\">DISABLE TRIGGER TR_UPD_Locations2 on Locations<\/pre>\n<\/p>\n<p>\n  <img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"500px\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2019\/05\/disable-a-trigger-on-the-table.png\" alt=\"Disable a trigger on the table\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"500px\" src=\"\/wp-content\/uploads\/2019\/05\/disable-a-trigger-on-the-table.png\" alt=\"Disable a trigger on the table\" \/><\/noscript>\n<\/p>\n<p>\n  Enabling specific trigger on the table using T-SQL.\n<\/p>\n<p><pre lang=\"tsql\">ENABLE TRIGGER TR_UPD_Locations2 on Locations<\/pre>\n<\/p>\n<p>\n  To enable all triggers on a table, use below syntax.\n<\/p>\n<p><pre lang=\"tsql\">ENABLE TRIGGER ALL ON Locations<\/pre>\n<\/p>\n<p>\n  To disable all triggers on a table, use below syntax. This statement is not supported if the table is part of merge replication.\n<\/p>\n<p><pre lang=\"tsql\">DISABLE TRIGGER ALL ON Locations<\/pre>\n<\/p>\n<h3>Dropping a trigger on a table.<\/h3>\n<p>\n  To drop a DML trigger on the table using SQL Server management studio, navigate to the <strong>Triggers<\/strong> folder under the table. Select the table you want to drop, Right click on the trigger and click on <strong>Delete<\/strong>. Click <strong>Ok<\/strong>.\n<\/p>\n<p>\n  <img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"450px\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2019\/05\/drop-a-trigger-on-the-table.png\" alt=\"drop a trigger on the table\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"450px\" src=\"\/wp-content\/uploads\/2019\/05\/drop-a-trigger-on-the-table.png\" alt=\"drop a trigger on the table\" \/><\/noscript>\n<\/p>\n<p>\n  T-SQL to drop a trigger on the table.\n<\/p>\n<p><pre lang=\"tsql\">DROP TRIGGER TRL_UPD_Locations2<\/pre>\n<\/p>\n<p>\n  Dropping a table will drop all the SQL Server triggers on the table along with the table.\n<\/p>\n<h2>DDL Triggers<\/h2>\n<p>\n  DDL triggers in SQL Server are fired on DDL events. i.e. against create, alter and drop statements, etc. These triggers are created at the database level or server level based on the type of DDL event.\n<\/p>\n<p>\n  These triggers are useful in the below cases.\n<\/p>\n<ul>\n<li>\n    Prevent changes to the database schema\n  <\/li>\n<li>\n    Audit database schema changes\n  <\/li>\n<li>\n    To respond to a change in the database schema\n  <\/li>\n<\/ul>\n<h3>Creating a DDL trigger<\/h3>\n<p>\n  Below is the sample syntax for creating a DDL trigger for ALTER TABLE event on a database which records all the alter statements against the table. You can write your custom code to track or audit the schema changes using EVENTDATA().\n<\/p>\n<p><pre lang=\"tsql\">CREATE TABLE TableSchemaChanges (ChangeEvent xml, DateModified datetime)\r\n\r\nCREATE TRIGGER TR_ALTERTABLE ON DATABASE\r\nFOR ALTER_TABLE\r\nAS\r\nBEGIN\r\n\r\nINSERT INTO TableSchemaChanges\r\nSELECT EVENTDATA(),GETDATE()\r\n\r\nEND<\/pre>\n<\/p>\n<p>\n  <img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"550px\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2019\/05\/sql-server-triggerddl-on-database.png\" alt=\"SQL Server trigger(DDL) on database\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"550px\" src=\"\/wp-content\/uploads\/2019\/05\/sql-server-triggerddl-on-database.png\" alt=\"SQL Server trigger(DDL) on database\" \/><\/noscript>\n<\/p>\n<p>\n  You can specify an event group which consists of different DDL events. If we specify an event group while creating a DDL trigger, the trigger is fired when a DDL event in the group occurs.\n<\/p>\n<p>\n  For example, if we want to create a trigger for all DDL events at the database level, we can just specify the DDL_DATABASE_LEVEL_EVENTS event group as shown in the below image.\n<\/p>\n<p>\n  <img decoding=\"async\" style=\"margin: 0px auto; display: block;\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2019\/05\/ddl-trigger-for-all-database-level-ddl-events.png\" width=\"450px\" alt=\"DDL trigger for all database level ddl events\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\" src=\"\/wp-content\/uploads\/2019\/05\/ddl-trigger-for-all-database-level-ddl-events.png\" width=\"450px\" alt=\"DDL trigger for all database level ddl events\" \/><\/noscript>\n<\/p>\n<p>\n  To view database level triggers, Login to the server using SQL Server management studio and navigate to the database. Expand the database and navigate to <strong>Programmability<\/strong> -&gt; <strong>Database Triggers.<\/strong>\n<\/p>\n<p>\n  <img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"400px\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2019\/05\/ddl-trigger-at-database-level.png\" alt=\"DDL trigger at database level\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"400px\" src=\"\/wp-content\/uploads\/2019\/05\/ddl-trigger-at-database-level.png\" alt=\"DDL trigger at database level\" \/><\/noscript>\n<\/p>\n<p>\n  To view triggers at the server level, Login to Server using SSMS and navigate to <strong>Server Objects<\/strong> and then <strong>Triggers<\/strong> folder.\n<\/p>\n<p>\n  <img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"500px\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2019\/05\/sql-server-trigger-server-level.png\" alt=\"SQL Server trigger - Server level\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\" width=\"500px\" src=\"\/wp-content\/uploads\/2019\/05\/sql-server-trigger-server-level.png\" alt=\"SQL Server trigger - Server level\" \/><\/noscript>\n<\/p>\n<h3>Enabling and disabling DDL triggers<\/h3>\n<p>\n  Use below T-SQL syntax to disable or enable the DDL trigger at the database level.\n<\/p>\n<p><pre lang=\"tsql\">ENABLE TRIGGER TR_DATABASEEVENTS ON DATABASE\r\nGO\r\n\r\nDISABLE TRIGGER TR_DATABASEEVENTS ON DATABASE\r\nGO<\/pre>\n<\/p>\n<p>\n  Use below T-SQL syntax to drop a DDL trigger which is created at the database level.\n<\/p>\n<p><pre lang=\"tsql\">DROP TRIGGER TR_DATABASEEVENTS ON DATABASE<\/pre>\n<\/p>\n<h2>LOGON Triggers in SQL Server<\/h2>\n<p>\n  These triggers in SQL Server fire in response to a LOGON event. LOGON triggers fire after successful authentication and before establishing the user session.\n<\/p>\n<p>\n  LOGON triggers are created at the server level and are useful below cases.\n<\/p>\n<ol>\n<li>\n  To audit login activity\n<\/li>\n<li>\n  To control the login activity\n<\/li>\n<\/ol>\n<h3>Creating LOGON triggers<\/h3>\n<p>\n  You can use EVENTDATA() and write your custom code to track or control the connections. Here I am creating simple triggers in SQL Server for LOGON event. Below is the sample syntax for creating a LOGON trigger.\n<\/p>\n<p><pre lang=\"tsql\">CREATE TABLE LoginActivity (LOGONEvent XML ,Logintime datetime)\r\n\r\nCREATE TRIGGER [track_logins] ON ALL SERVER\r\nFOR LOGON AS\r\n\r\nBEGIN\r\n  INSERT INTO LoginActivity\r\n  SELECT EVENTDATA()\r\n    ,GETDATE()\r\nEND<\/pre>\n<\/p>\n<p>\n  We must be cautious while creating these triggers as login may fail if the trigger execution fails or if you do not have access to objects referenced in the LOGON trigger. In such cases, the only member of the sysadmin role can connect to the server using a dedicated administrator connection. So, it is always better to enable dedicated administrator connection when using these triggers.\n<\/p>\n<h3>Enabling and disabling LOGON triggers<\/h3>\n<p>\n  Use below T-SQL syntax to disable or enable the LOGON trigger.\n<\/p>\n<p><pre lang=\"tsql\">ENABLE TRIGGER track_logins ON ALL SERVER\r\nGO\r\n\r\nDISABLE TRIGGER track_logins ON ALL SERVER\r\nGO<\/pre>\n<\/p>\n<p>\n  Use below T-SQL syntax to drop a LOGON trigger.\n<\/p>\n<p><pre lang=\"tsql\">DROP TRIGGER track_logins ON ALL SERVER<\/pre>\n<\/p>\n<h2>Direct recursion<\/h2>\n<p>\n  Direct recursion is a case where the SQL Server trigger on the table is fired and performs an action which again triggers the same trigger.\n<\/p>\n<p>\n  For example, please refer to below sample trigger for an update which is direct recursive.\n<\/p>\n<p><pre lang=\"tsql\">SET ANSI_NULLS ON\r\nGO\r\n\r\nSET QUOTED_IDENTIFIER ON\r\nGO\r\n\r\nCREATE TABLE [dbo].[Locations](\r\n  [LocationID] [int] NULL,\r\n  [LocName] [varchar](100) NULL,\r\n  DateUpdated datetime\r\n) ON [PRIMARY]\r\nGO\r\n\r\nINSERT INTO Locations VALUES(1,'Richmond Road', NULL)\r\n\r\nCREATE TRIGGER TR_UPD_Locations ON Locations\r\nFOR UPDATE \r\nAS\r\n\r\nBEGIN\r\n  Update Locations set DateUpdated =GETDATE()\r\nEND<\/pre>\n<\/p>\n<p>\n  Direct recursion can be controlled by a database setting <strong>RECURSIVE_TRIGGERS<\/strong>. If the setting is on, then the above trigger throws an error.\n<\/p>\n<p>\n  <img decoding=\"async\" style=\"margin: 0px auto; display: block;\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2019\/05\/direct-recursive-triggers-in-sql-server.png\" width=\"550px\" alt=\"Direct recursive triggers in SQL Server\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\" src=\"\/wp-content\/uploads\/2019\/05\/direct-recursive-triggers-in-sql-server.png\" width=\"550px\" alt=\"Direct recursive triggers in SQL Server\" \/><\/noscript>\n<\/p>\n<p>\n  If the database setting RECURSIVE_TRIGGERS is off, then the trigger is fired only once and does not loop.\n<\/p>\n<p>\n  <img decoding=\"async\" style=\"margin: 0px auto; display: block;\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2019\/05\/direct-recursive-triggers-with-recursive-setting-o.png\" width=\"550px\" alt=\"Direct recursive triggers with recursive setting off\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\" src=\"\/wp-content\/uploads\/2019\/05\/direct-recursive-triggers-with-recursive-setting-o.png\" width=\"550px\" alt=\"Direct recursive triggers with recursive setting off\" \/><\/noscript><\/p>\n<p>\n  To change RECURSIVE_TRIGGERS setting using SSMS, navigate to the database, right click on the database and select <strong>Properties. <\/strong>Click on <strong>Options<\/strong> and change the setting to the option you want.\n<\/p>\n<p>\n  <img decoding=\"async\" style=\"margin: 0px auto; display: block;\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2019\/05\/sql-server-trigger-recursive-settings.png\" alt=\"SQL Server trigger - Recursive settings\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\" src=\"\/wp-content\/uploads\/2019\/05\/sql-server-trigger-recursive-settings.png\" alt=\"SQL Server trigger - Recursive settings\" \/><\/noscript>\n<\/p>\n<p>\n  To set the RECURSIVE_TRIGGERS OFF using T-SQL, use below statement and replace the database name with your database name.\n<\/p>\n<p><pre lang=\"tsql\">ALTER DATABASE [AdventureWorks] SET RECURSIVE_TRIGGERS OFF WITH NO_WAIT\r\nGO<\/pre>\n<\/p>\n<p>\n  To set the RECURSIVE_TRIGGERS ON using T-SQL, use below statement and replace the database name with your database name.\n<\/p>\n<p><pre lang=\"tsql\">ALTER DATABASE [AdventureWorks] SET RECURSIVE_TRIGGERS ON WITH NO_WAIT\r\nGO<\/pre>\n<\/p>\n<h2>Indirect Recursion<\/h2>\n<p>\n  This is a case where a trigger is fired and invokes another trigger of the same type.\n<\/p>\n<p>\n  Below is the sample trigger for indirect recursion.\n<\/p>\n<p><pre lang=\"tsql\">CREATE TABLE Temp1 (id int)\r\nGO\r\n\r\nINSERT INTO Temp1 values (1),(2)\r\nGO\r\n\r\nCREATE TABLE Temp2 (id int)\r\nGO\r\n\r\nINSERT INTO Temp2 values (1),(2)\r\nGO\r\n\r\nCREATE TRIGGER TR_Temp1 on Temp1\r\nFOR UPDATE \r\nAS\r\nBEGIN\r\nUPDATE TEMP2 set ID ='5' where id in (select id from inserted)\r\nEND\r\nGO\r\n\r\nCREATE TRIGGER TR_Temp2 on Temp2\r\nFOR UPDATE \r\nAS\r\nBEGIN\r\nUPDATE Temp1 set ID ='5' where id in (select id from inserted)\r\nEND<\/pre>\n<\/p>\n<p>\n  Now when we update a value in the table Temp1, the trigger TR_Temp1 is fired which updates Temp2 table. TR_Temp2 is fired and updates Temp1 table which causes TR_Temp1 to fire again.\n<\/p>\n<p>\n  <img decoding=\"async\" style=\"margin: 0px auto; display: block;\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2019\/05\/indirect-recursion-of-triggers-in-sql-server.png\" alt=\"indirect recursion of triggers in SQL Server\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\" src=\"\/wp-content\/uploads\/2019\/05\/indirect-recursion-of-triggers-in-sql-server.png\" alt=\"indirect recursion of triggers in SQL Server\" \/><\/noscript>\n<\/p>\n<p>\n  This behavior can be controlled by setting <strong>nested triggers<\/strong> off.\n<\/p>\n<p><pre lang=\"tsql\">EXEC sp_configure 'nested triggers', 0 ;  \r\nGO<\/pre>\n<\/p>\n<h2>SQL Server trigger order<\/h2>\n<p>\n  SQL Server allows multiple triggers on the table for the same event and there is no defined order of execution of these triggers.\n<\/p>\n<p>\n  We can set the order of a trigger to either first or last using procedure sp_settriggerorder. There can be only one first or last trigger for each statement on a table.\n<\/p>\n<p>\n  Below is the sample syntax for setting the order of trigger to first for the INSERT statement.\n<\/p>\n<p><pre lang=\"tsql\">CREATE TABLE TriggerOrderTest (id int)\r\nGO\r\n\r\nCREATE TRIGGER TR_1 ON TriggerOrderTest\r\nFOR INSERT\r\nas\r\nBEGIN\r\nPRINT 'First Trigger'\r\nEND\r\nGO\r\n\r\nCREATE TRIGGER TR_2 ON TriggerOrderTest\r\nFOR INSERT\r\nas\r\nBEGIN\r\nPRINT 'Second Trigger'\r\nEND\r\nGO\r\n\r\nCREATE TRIGGER TR_3 ON TriggerOrderTest\r\nFOR INSERT\r\nas\r\nBEGIN\r\nPRINT 'Third Trigger'\r\nEND\r\nGO\r\n\r\nsp_settriggerorder  @triggername ='TR_3'\r\n    ,  @order = 'FIRST'   \r\n    ,  @stmttype =  'INSERT'<\/pre>\n<\/p>\n<p>\n  Now, when the data is inserted into the table \u201cTriggerOrderTest\u201d INSERT event occurs and the trigger TR_3 fires first.\n<\/p>\n<p>\n  <img decoding=\"async\" style=\"margin: 0px auto; display: block;\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"\/wp-content\/uploads\/2019\/05\/trigger-order.png\" width=\"500px\" alt=\"trigger order\" \/><noscript><img decoding=\"async\" style=\"margin: 0px auto; display: block;\" src=\"\/wp-content\/uploads\/2019\/05\/trigger-order.png\" width=\"500px\" alt=\"trigger order\" \/><\/noscript>\n<\/p>\n<p>\n  In case DDL triggers we must specify the namespace parameter which is the scope of the SQL Server trigger in the stored procedure sp_settriggerorder.\n<\/p>\n<p>\n  Below is the sample syntax for setting the DDL trigger order.\n<\/p>\n<p><pre lang=\"tsql\">sp_settriggerorder  @triggername ='DDL_3'\r\n    ,  @order = 'FIRST'   \r\n    ,  @stmttype =  'ALTER_TABLE'   \r\n   ,  @namespace =   'DATABASE'<\/pre>\n<\/p>\n<h2>NOT FOR REPLICATION<\/h2>\n<\/p>\n<p>\n  NOT FOR REPLICATION indicates that the trigger should not fire when the replication agent syncs the data changes to the subscriber.\n<\/p>\n<p>\n  For example, if you are replicating both Locations and LocationHist. Now when you update a record on Location the trigger is fired, inserts record in the history table. When these changes sync to another end (subscribers) there is no need of trigger to be fired again. So, if we mark the trigger for \u201cNOT FOR REPLICATION\u201d the trigger does not fire when replication agent sync\u2019s the changes and fires only for the data changes done by the user.\n<\/p>\n<p>\n  Below is the sample syntax to create a triggers in SQL Server with not for replication.\n<\/p>\n<p><pre lang=\"tsql\">CREATE TRIGGER TR_UPD_Locations ON Locations\r\nFOR UPDATE \r\nNOT FOR REPLICATION \r\nAS\r\n\r\nBEGIN\r\n  INSERT INTO LocationHist\r\n  SELECT LocationID\r\n    ,getdate()\r\n  FROM inserted\r\nEND<\/pre>\n<\/p>\n<p>\n  If you want the triggers in SQL Server to be fired when the replication agent sync data changes to another end, just create the trigger without specifying \u201cNOT FOR REPLICATION\u201d.\n<\/p>\n<div id=\"see_more\"><\/div>\n<p><script> <\/p>\n<p>display_see_more(text='trigger', video='trigger', banner='trigger', banner_link='trigger'); <\/p>\n<p><\/script> <\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>In this article, we will review triggers in SQL Server, different types of trigger events, trigger order and NOT FOR REPLICATION in triggers. A trigger is a database object that runs automatically when an event occurs. There are three different types of events.<!-- AddThis Advanced Settings generic via filter on wp_trim_excerpt --><!-- AddThis Share Buttons generic via filter on wp_trim_excerpt --><\/p>\n","protected":false},"author":129,"featured_media":47883,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-47849","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sql-server-auditing"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Triggers in SQL Server<\/title>\n<meta name=\"description\" content=\"In this article, we will review triggers in SQL Server, different types of trigger events, trigger order and NOT FOR REPLICATION in triggers.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.sqlshack.com\/triggers-in-sql-server\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Triggers in SQL Server\" \/>\n<meta property=\"og:description\" content=\"In this article, we will review triggers in SQL Server, different types of trigger events, trigger order and NOT FOR REPLICATION in triggers.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.sqlshack.com\/triggers-in-sql-server\/\" \/>\n<meta property=\"og:site_name\" content=\"SQL Shack - articles about database auditing, server performance, data recovery, and more\" \/>\n<meta property=\"article:published_time\" content=\"2019-05-15T12:42:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-05-15T16:51:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2019\/05\/direct-recursive-triggers-in-sql-server.png\" \/>\n\t<meta property=\"og:image:width\" content=\"874\" \/>\n\t<meta property=\"og:image:height\" content=\"493\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Ranga Babu\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@CherukuriRanga\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Ranga Babu\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/triggers-in-sql-server\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/triggers-in-sql-server\\\/\"},\"author\":{\"name\":\"Ranga Babu\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#\\\/schema\\\/person\\\/54e135d6de2c95f7fe3de5c45a4970f7\"},\"headline\":\"Triggers in SQL Server\",\"datePublished\":\"2019-05-15T12:42:44+00:00\",\"dateModified\":\"2019-05-15T16:51:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/triggers-in-sql-server\\\/\"},\"wordCount\":1434,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/triggers-in-sql-server\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.sqlshack.com\\\/wp-content\\\/uploads\\\/2019\\\/05\\\/direct-recursive-triggers-in-sql-server.png\",\"articleSection\":[\"Auditing\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/triggers-in-sql-server\\\/\",\"url\":\"https:\\\/\\\/www.sqlshack.com\\\/triggers-in-sql-server\\\/\",\"name\":\"Triggers in SQL Server\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/triggers-in-sql-server\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/triggers-in-sql-server\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.sqlshack.com\\\/wp-content\\\/uploads\\\/2019\\\/05\\\/direct-recursive-triggers-in-sql-server.png\",\"datePublished\":\"2019-05-15T12:42:44+00:00\",\"dateModified\":\"2019-05-15T16:51:45+00:00\",\"description\":\"In this article, we will review triggers in SQL Server, different types of trigger events, trigger order and NOT FOR REPLICATION in triggers.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.sqlshack.com\\\/triggers-in-sql-server\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/triggers-in-sql-server\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.sqlshack.com\\\/wp-content\\\/uploads\\\/2019\\\/05\\\/direct-recursive-triggers-in-sql-server.png\",\"contentUrl\":\"https:\\\/\\\/www.sqlshack.com\\\/wp-content\\\/uploads\\\/2019\\\/05\\\/direct-recursive-triggers-in-sql-server.png\",\"width\":874,\"height\":493,\"caption\":\"Direct recursive triggers in SQL Server\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#website\",\"url\":\"https:\\\/\\\/www.sqlshack.com\\\/\",\"name\":\"SQL Shack - articles about database auditing, server performance, data recovery, and more\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.sqlshack.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#organization\",\"name\":\"SQL Shack\",\"url\":\"https:\\\/\\\/www.sqlshack.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.sqlshack.com\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/sqlshack-default.png\",\"contentUrl\":\"https:\\\/\\\/www.sqlshack.com\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/sqlshack-default.png\",\"width\":1200,\"height\":630,\"caption\":\"SQL Shack\"},\"image\":{\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.sqlshack.com\\\/#\\\/schema\\\/person\\\/54e135d6de2c95f7fe3de5c45a4970f7\",\"name\":\"Ranga Babu\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/7c4e0b8fe0806680bccad7cedac4d6ed3b9beab255ff47f3ca9551a310a50eab?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/7c4e0b8fe0806680bccad7cedac4d6ed3b9beab255ff47f3ca9551a310a50eab?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/7c4e0b8fe0806680bccad7cedac4d6ed3b9beab255ff47f3ca9551a310a50eab?s=96&d=mm&r=g\",\"caption\":\"Ranga Babu\"},\"description\":\"SQL Server DBA, Developer with good experience in SQL Server administration, development, performance tuning, monitoring, high availability and disaster recovery technologies\",\"sameAs\":[\"https:\\\/\\\/x.com\\\/CherukuriRanga\"],\"url\":\"https:\\\/\\\/www.sqlshack.com\\\/author\\\/ranga-babu\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Triggers in SQL Server","description":"In this article, we will review triggers in SQL Server, different types of trigger events, trigger order and NOT FOR REPLICATION in triggers.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.sqlshack.com\/triggers-in-sql-server\/","og_locale":"en_US","og_type":"article","og_title":"Triggers in SQL Server","og_description":"In this article, we will review triggers in SQL Server, different types of trigger events, trigger order and NOT FOR REPLICATION in triggers.","og_url":"https:\/\/www.sqlshack.com\/triggers-in-sql-server\/","og_site_name":"SQL Shack - articles about database auditing, server performance, data recovery, and more","article_published_time":"2019-05-15T12:42:44+00:00","article_modified_time":"2019-05-15T16:51:45+00:00","og_image":[{"width":874,"height":493,"url":"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2019\/05\/direct-recursive-triggers-in-sql-server.png","type":"image\/png"}],"author":"Ranga Babu","twitter_card":"summary_large_image","twitter_creator":"@CherukuriRanga","twitter_misc":{"Written by":"Ranga Babu","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.sqlshack.com\/triggers-in-sql-server\/#article","isPartOf":{"@id":"https:\/\/www.sqlshack.com\/triggers-in-sql-server\/"},"author":{"name":"Ranga Babu","@id":"https:\/\/www.sqlshack.com\/#\/schema\/person\/54e135d6de2c95f7fe3de5c45a4970f7"},"headline":"Triggers in SQL Server","datePublished":"2019-05-15T12:42:44+00:00","dateModified":"2019-05-15T16:51:45+00:00","mainEntityOfPage":{"@id":"https:\/\/www.sqlshack.com\/triggers-in-sql-server\/"},"wordCount":1434,"commentCount":0,"publisher":{"@id":"https:\/\/www.sqlshack.com\/#organization"},"image":{"@id":"https:\/\/www.sqlshack.com\/triggers-in-sql-server\/#primaryimage"},"thumbnailUrl":"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2019\/05\/direct-recursive-triggers-in-sql-server.png","articleSection":["Auditing"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.sqlshack.com\/triggers-in-sql-server\/","url":"https:\/\/www.sqlshack.com\/triggers-in-sql-server\/","name":"Triggers in SQL Server","isPartOf":{"@id":"https:\/\/www.sqlshack.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.sqlshack.com\/triggers-in-sql-server\/#primaryimage"},"image":{"@id":"https:\/\/www.sqlshack.com\/triggers-in-sql-server\/#primaryimage"},"thumbnailUrl":"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2019\/05\/direct-recursive-triggers-in-sql-server.png","datePublished":"2019-05-15T12:42:44+00:00","dateModified":"2019-05-15T16:51:45+00:00","description":"In this article, we will review triggers in SQL Server, different types of trigger events, trigger order and NOT FOR REPLICATION in triggers.","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.sqlshack.com\/triggers-in-sql-server\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sqlshack.com\/triggers-in-sql-server\/#primaryimage","url":"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2019\/05\/direct-recursive-triggers-in-sql-server.png","contentUrl":"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2019\/05\/direct-recursive-triggers-in-sql-server.png","width":874,"height":493,"caption":"Direct recursive triggers in SQL Server"},{"@type":"WebSite","@id":"https:\/\/www.sqlshack.com\/#website","url":"https:\/\/www.sqlshack.com\/","name":"SQL Shack - articles about database auditing, server performance, data recovery, and more","description":"","publisher":{"@id":"https:\/\/www.sqlshack.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.sqlshack.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.sqlshack.com\/#organization","name":"SQL Shack","url":"https:\/\/www.sqlshack.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sqlshack.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2019\/03\/sqlshack-default.png","contentUrl":"https:\/\/www.sqlshack.com\/wp-content\/uploads\/2019\/03\/sqlshack-default.png","width":1200,"height":630,"caption":"SQL Shack"},"image":{"@id":"https:\/\/www.sqlshack.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.sqlshack.com\/#\/schema\/person\/54e135d6de2c95f7fe3de5c45a4970f7","name":"Ranga Babu","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/7c4e0b8fe0806680bccad7cedac4d6ed3b9beab255ff47f3ca9551a310a50eab?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/7c4e0b8fe0806680bccad7cedac4d6ed3b9beab255ff47f3ca9551a310a50eab?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/7c4e0b8fe0806680bccad7cedac4d6ed3b9beab255ff47f3ca9551a310a50eab?s=96&d=mm&r=g","caption":"Ranga Babu"},"description":"SQL Server DBA, Developer with good experience in SQL Server administration, development, performance tuning, monitoring, high availability and disaster recovery technologies","sameAs":["https:\/\/x.com\/CherukuriRanga"],"url":"https:\/\/www.sqlshack.com\/author\/ranga-babu\/"}]}},"_links":{"self":[{"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/posts\/47849","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/users\/129"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/comments?post=47849"}],"version-history":[{"count":14,"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/posts\/47849\/revisions"}],"predecessor-version":[{"id":47993,"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/posts\/47849\/revisions\/47993"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/media\/47883"}],"wp:attachment":[{"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/media?parent=47849"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/categories?post=47849"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlshack.com\/wp-json\/wp\/v2\/tags?post=47849"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}