Skip to main content

What are Triggers

Editorial

Introduction

Imagine you want the database to automatically log every time someone deletes a customer record, or automatically update an inventory count whenever a new order is placed. You could add this logic to every application that touches the database — but that is error-prone and hard to maintain. What if you could tell the database itself to perform these actions automatically?

That is exactly what triggers do.

In this tutorial, you will learn:

  • What triggers are and how they differ from stored procedures
  • The different types of triggers
  • How triggers fire in response to data changes
  • The special INSERTED and DELETED tables
  • How to create, modify, and remove triggers
  • When triggers are appropriate and when to avoid them

What is a Trigger?

Definition

A trigger is a special type of stored procedure that runs automatically when a specific event occurs on a table. You do not call a trigger manually — it fires on its own in response to INSERT, UPDATE, or DELETE operations.

Simple Analogy

Think of a trigger like a motion-sensor light. You do not flip a switch — the light turns on automatically when it detects movement. Similarly, a trigger activates automatically when it detects a data change on its table.

Flowchart showing how a trigger automatically fires in response to INSERT, UPDATE, or DELETE events on a table

Triggers vs Stored Procedures

Key Differences

FeatureStored ProcedureTrigger
InvocationManually called with EXECAutomatically fired by events
ParametersCan accept input/output paramsNo parameters
Attached toDatabase (standalone)A specific table
When it runsWhen you call itOn INSERT, UPDATE, or DELETE
Can be called directlyYesNo
Return valuesYes (result sets, output params)No
Transaction contextCreates its ownRuns within the triggering statement's transaction

Important: Transaction Behavior

A trigger runs inside the same transaction as the statement that caused it. This means:

  • If the trigger fails, the original statement is rolled back
  • If the trigger succeeds but the transaction is rolled back, the trigger's changes are also rolled back

This is a very powerful feature — and also a common source of unexpected behavior.

Types of Triggers

DML Triggers (Most Common)

DML triggers fire in response to Data Manipulation Language operations on a table.

Trigger EventFires When
INSERTA new row is added to the table
UPDATEAn existing row is modified
DELETEA row is removed from the table

Timing: AFTER vs INSTEAD OF

TypeWhen It RunsUse Case
AFTER (default)After the triggering statement completesLogging, auditing, cascading changes
INSTEAD OFReplaces the triggering statement entirelyCustom validation, view updates
Generated visual representation from text diagram for Types of Triggers.

DDL Triggers

DDL triggers fire on Data Definition Language operations like CREATE TABLE, ALTER TABLE, or DROP TABLE. These are less common and used primarily for database administration and governance.

Logon Triggers

Logon triggers fire when a user session is established. They are used for security auditing and session management.

The INSERTED and DELETED Tables

Magic Tables

When a trigger fires, SQL Server provides two special temporary tables that contain the data involved in the operation:

TableContainsAvailable In
INSERTEDNew rows (the data being added or the new version after update)INSERT, UPDATE triggers
DELETEDOld rows (the data being removed or the old version before update)DELETE, UPDATE triggers

How They Work for Each Operation

Generated visual representation from text diagram for The INSERTED and DELETED Tables.

These tables have the exact same structure (columns) as the table the trigger is attached to.

Creating a Trigger

Basic Syntax (SQL Server)

CREATE TRIGGER trigger_name
ON table_name
AFTER INSERT | UPDATE | DELETE
AS
BEGIN
    -- Trigger logic here
END;

Components

ComponentPurpose
CREATE TRIGGERCreates a new trigger
trigger_nameUnique name for the trigger
ON table_nameThe table the trigger is attached to
AFTER INSERTWhen the trigger fires (event type)
AS BEGIN...ENDThe body containing the trigger logic
-- Trigger that logs every new order insertion
CREATE TRIGGER trg_OrderInserted
ON orders
AFTER INSERT
AS
BEGIN
    SET NOCOUNT ON;

    -- Log the new order into an audit table
    INSERT INTO order_audit_log (
        order_id,
        action,
        action_timestamp
    )
    SELECT 
        order_id,
        'INSERT',
        GETDATE()
    FROM INSERTED;
END;

How This Works

  1. Someone runs INSERT INTO orders VALUES (...)
  2. The row is inserted into the orders table
  3. SQL Server detects the INSERT and fires trg_OrderInserted
  4. The trigger reads the new row from the INSERTED table
  5. The trigger inserts a log entry into order_audit_log

All of this happens automatically — the person inserting the order does not even know the trigger exists.

Trigger for Multiple Events

Handling INSERT, UPDATE, and DELETE in One Trigger

You can create a single trigger that fires on multiple events.

-- Single trigger handling multiple events
CREATE TRIGGER trg_OrderChanges
ON orders
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @Action NVARCHAR(10);

    -- Determine which action triggered this
    IF EXISTS (SELECT 1 FROM INSERTED) AND EXISTS (SELECT 1 FROM DELETED)
        SET @Action = 'UPDATE';
    ELSE IF EXISTS (SELECT 1 FROM INSERTED)
        SET @Action = 'INSERT';
    ELSE
        SET @Action = 'DELETE';

    -- Log the action
    IF @Action IN ('INSERT', 'UPDATE')
    BEGIN
        INSERT INTO order_audit_log (order_id, action, new_status, action_timestamp)
        SELECT order_id, @Action, order_status, GETDATE()
        FROM INSERTED;
    END

    IF @Action = 'DELETE'
    BEGIN
        INSERT INTO order_audit_log (order_id, action, new_status, action_timestamp)
        SELECT order_id, @Action, order_status, GETDATE()
        FROM DELETED;
    END
END;

How to Detect the Action Type

ConditionAction
INSERTED has rows AND DELETED has rowsUPDATE
INSERTED has rows AND DELETED is emptyINSERT
INSERTED is empty AND DELETED has rowsDELETE

Managing Triggers

Modifying a Trigger

ALTER TRIGGER trigger_name
ON table_name
AFTER INSERT
AS
BEGIN
    -- Updated trigger logic
END;

Dropping a Trigger

DROP TRIGGER trigger_name;

-- Safe drop
DROP TRIGGER IF EXISTS trigger_name;

Disabling and Enabling Triggers

Sometimes you need to temporarily turn off a trigger (for example, during a bulk data load):

-- Disable a specific trigger
DISABLE TRIGGER trg_OrderInserted ON orders;

-- Re-enable it
ENABLE TRIGGER trg_OrderInserted ON orders;

-- Disable ALL triggers on a table
DISABLE TRIGGER ALL ON orders;

-- Re-enable ALL triggers on a table
ENABLE TRIGGER ALL ON orders;

Viewing Existing Triggers

-- List all triggers in the database
SELECT 
    name AS trigger_name,
    OBJECT_NAME(parent_id) AS table_name,
    is_disabled
FROM sys.triggers
ORDER BY table_name, trigger_name;

When to Use and Avoid Triggers

Good Use Cases for Triggers

Use CaseDescription
Audit loggingTrack who changed what and when
Data validationEnforce complex business rules
Cascading updatesAutomatically update related tables
Maintaining derived dataKeep summary/aggregate tables in sync
Security enforcementPrevent unauthorized changes

When to Avoid Triggers

ConcernWhy
Complex business logicHard to debug; use stored procedures instead
Performance-critical pathsTriggers add overhead to every DML operation
Cascading triggersTrigger A fires Trigger B fires Trigger C — nightmare
Hidden logicDevelopers may not realize triggers exist
Heavy processingTriggers should be fast; offload heavy work elsewhere

The Hidden Logic Problem

Generated visual representation from text diagram for When to Use and Avoid Triggers.

Best Practice: Document all triggers thoroughly. Any developer working with a table should know what triggers exist on it.

MySQL Trigger Syntax

MySQL triggers use a slightly different syntax:

-- MySQL: Creating a trigger
DELIMITER //

CREATE TRIGGER trg_order_inserted
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
    -- In MySQL, use NEW and OLD instead of INSERTED/DELETED
    INSERT INTO order_audit_log (order_id, action, action_timestamp)
    VALUES (NEW.order_id, 'INSERT', NOW());
END //

DELIMITER ;

Key Differences

FeatureSQL ServerMySQL
New data referenceINSERTED tableNEW.column_name
Old data referenceDELETED tableOLD.column_name
Timing keywordsAFTER, INSTEAD OFBEFORE, AFTER
Row scopeSet-based (all affected rows)Row-by-row (FOR EACH ROW)
Multiple eventsAFTER INSERT, UPDATESeparate trigger per event

Summary

Key Takeaways

ConceptWhat You Learned
WhatTriggers are auto-firing stored procedures attached to tables
WhenThey fire on INSERT, UPDATE, or DELETE events
INSERTED/DELETEDSpecial tables holding new and old row data
AFTER vs INSTEAD OFRun after the event vs replace the event
CautionTriggers add hidden complexity — use wisely

What is Next?

In the next tutorial, we will explore trigger use cases — real-world scenarios where triggers provide significant value, with complete working examples you can adapt for your own projects.