11. Triggers

Triggers in SQL

A trigger is a named set of T-SQL (or SQL) commands that automatically executes in response to certain events, such as DDL operations (CREATE, ALTER, DROP) or DML operations (INSERT, UPDATE, DELETE).

Purpose of Triggers

DDL vs. DML Triggers

Types of DML Triggers

Temporary Tables for DML Triggers

When a DML trigger fires, SQL Server automatically creates two temporary tables (where applicable):

Example: AFTER UPDATE Trigger

CREATE TRIGGER BookUpdates
ON Books
AFTER UPDATE
AS
BEGIN
    PRINT @@ROWCOUNT;  -- Number of rows updated
END
GO

UPDATE Books
SET Pages = Pages + 1
WHERE Pages > 400;
GO

Example: AFTER INSERT Trigger with Validation

This trigger prevents adding a book if its YearPress is less than 2000.

CREATE TRIGGER OldBook
ON Books
AFTER INSERT
AS
BEGIN
    DECLARE @year INT;

    SELECT @year = YearPress
    FROM Inserted;

    IF (@year < 2000)
    BEGIN
        PRINT 'Year < 2000';
        ROLLBACK TRAN;  -- Undo the INSERT
    END
    ELSE
    BEGIN
        PRINT 'ok!';
    END
END
GO

-- Successful insert
INSERT INTO Books (Id, [Name], Pages, YearPress, Id_Themes, Id_Category, Id_Author, Id_Press, Quantity)
VALUES (100, N'Yeni kitab', 100, 2017, 2, 2, 2, 2, 5);

-- Fails due to trigger
INSERT INTO Books (Id, [Name], Pages, YearPress, Id_Themes, Id_Category, Id_Author, Id_Press, Quantity)
VALUES (99, N'Yeni kitab', 100, 1917, 2, 2, 2, 2, 5);

Example: AFTER DELETE Trigger with Restrictions

This trigger disallows deleting books from the BHV press.

CREATE TRIGGER NotBHV
ON Books
AFTER DELETE
AS
BEGIN
    DECLARE @id_bhv INT;

    SELECT @id_bhv = Id
    FROM Press
    WHERE [Name] LIKE 'BHV';

    IF EXISTS (
        SELECT *
        FROM Deleted
        WHERE Id_Press = @id_bhv
    )
    BEGIN
        PRINT 'Can not delete book from BHV!';
        ROLLBACK TRAN;
    END
END
GO

-- Attempting to delete a BHV book fails
DELETE
FROM Books
WHERE Id = 100;
GO

Example: INSTEAD OF Trigger

An INSTEAD OF trigger intercepts the action and replaces it.

CREATE TRIGGER NoInsertLibs
ON Libs
INSTEAD OF INSERT
AS
BEGIN
    PRINT 'No insert Libs';
END
GO

INSERT INTO Libs (Id, FirstName, LastName)
VALUES (5, N'qwqe', N'asd');

-- The above insert prints "No insert Libs" and does not insert any rows.
SELECT * FROM Libs;

DROP TRIGGER NoInsertLibs;
GO

General Rules and Restrictions

Reference

The content in this document is based on the original notes provided in Azerbaijani. For further details, you can refer to the original document using the following link:

Original Note - Azerbaijani Version