Create Multiple Triggers

Summary: in this tutorial, you will learn how to create multiple triggers for a table that have the same event and action time.

This tutorial is relevant to the MySQL version 5.7.2+. If you have an older version of MySQL, the statements in the tutorial will not work.

Before MySQL version 5.7.2, you could only create one trigger for an event in a table e.g., you could only create one trigger for the BEFORE UPDATE or AFTER UPDATE event.

MySQL 5.7.2+ lifted this limitation and allowed you to create multiple triggers for a given table that have the same event and action time. These triggers will activate sequentially when an event occurs.

Here is the syntax for defining a trigger that will activate before or after an existing trigger in response to the same event and action time:

DELIMITER $$

CREATE TRIGGER trigger_name
{BEFORE|AFTER}{INSERT|UPDATE|DELETE} 
ON table_name FOR EACH ROW 
{FOLLOWS|PRECEDES} existing_trigger_name
BEGIN
    -- statements
END$$

DELIMITER ;Code language: SQL (Structured Query Language) (sql)

In this syntax, the FOLLOWS or PRECEDES specifies whether the new trigger should be invoked before or after an existing trigger.

  • The FOLLOWS  allows the new trigger to activate after an existing trigger.
  • The PRECEDES  allows the new trigger to activate before an existing trigger.
MySQL Multiple Triggers

MySQL multiple triggers example

We will use the products table in the sample database for the demonstration.

Suppose that you want to change the price of a product (column MSRP ) and log the old price in a separate table named PriceLogs .

First, create a new price_logs table using the following CREATE TABLE statement:

CREATE TABLE PriceLogs (
    id INT AUTO_INCREMENT,
    productCode VARCHAR(15) NOT NULL,
    price DECIMAL(10,2) NOT NULL,
    updated_at TIMESTAMP NOT NULL 
			DEFAULT CURRENT_TIMESTAMP 
            ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    FOREIGN KEY (productCode)
        REFERENCES products (productCode)
        ON DELETE CASCADE 
        ON UPDATE CASCADE
);Code language: SQL (Structured Query Language) (sql)

Second, create a new trigger that activates when the BEFORE UPDATE event of the products table occurs:

DELIMITER $$

CREATE TRIGGER before_products_update 
   BEFORE UPDATE ON products 
   FOR EACH ROW 
BEGIN
     IF OLD.msrp <> NEW.msrp THEN
         INSERT INTO PriceLOgs(productCode,price)
         VALUES(old.productCode,old.msrp);
     END IF;
END$$

DELIMITER ;Code language: SQL (Structured Query Language) (sql)

Third, check the price of the product S12_1099:

SELECT 
    productCode, 
    msrp 
FROM 
    products
WHERE 
    productCode = 'S12_1099';Code language: SQL (Structured Query Language) (sql)

Third, change the price of a product using the following UPDATE statement:

UPDATE products
SET msrp = 200
WHERE productCode = 'S12_1099';Code language: SQL (Structured Query Language) (sql)

Fourth, query data from the PriceLogs table:

SELECT * FROM PriceLogs;Code language: SQL (Structured Query Language) (sql)

It works as expected.

Suppose that you want to log the user who changed the price. To achieve this, you can add an additional column to the PriceLogs table.

However, for the purpose of multiple triggers demonstration, we will create a new separate table to store the data of users who made the changes.

Fifth, create the UserChangeLogs table:

CREATE TABLE UserChangeLogs (
    id INT AUTO_INCREMENT,
    productCode VARCHAR(15) DEFAULT NULL,
    updatedAt TIMESTAMP NOT NULL 
	DEFAULT CURRENT_TIMESTAMP 
        ON UPDATE CURRENT_TIMESTAMP,
    updatedBy VARCHAR(30) NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (productCode)
        REFERENCES products (productCode)
        ON DELETE CASCADE 
        ON UPDATE CASCADE
);Code language: SQL (Structured Query Language) (sql)

Sixth, create a BEFORE UPDATE trigger for the products table. This trigger activates after the before_products_update trigger.

DELIMITER $$

CREATE TRIGGER before_products_update_log_user
   BEFORE UPDATE ON products 
   FOR EACH ROW 
   FOLLOWS before_products_update
BEGIN
    IF OLD.msrp <> NEW.msrp THEN
	INSERT INTO 
            UserChangeLogs(productCode,updatedBy)
        VALUES
            (OLD.productCode,USER());
    END IF;
END$$

DELIMITER ;Code language: HTML, XML (xml)

Let’s do a quick test.

Seventh, update the price of a product using the following UPDATE statement:

UPDATE 
    products
SET 
    msrp = 220
WHERE 
    productCode = 'S12_1099';Code language: SQL (Structured Query Language) (sql)

Eighth, query data from both PriceLogs and UserChangeLogs tables:

SELECT * FROM PriceLogs;Code language: SQL (Structured Query Language) (sql)
MySQL Multiple Trigger Price Log 2
SELECT * FROM UserChangeLogs;Code language: SQL (Structured Query Language) (sql)
MySQL Multiple Trigger User Log

As you can see, both triggers were activated in the sequence as expected.

Information on trigger order

If you use the SHOW TRIGGERS statement to show the triggers, you will not see the order that triggers activated for the same event and action time.

SHOW TRIGGERS 
FROM classicmodels
WHERE `table` = 'products';Code language: SQL (Structured Query Language) (sql)

To find this information, you need to query the action_order column in the triggers table of the information_schema database as follows:

SELECT 
    trigger_name, 
    action_order
FROM
    information_schema.triggers
WHERE
    trigger_schema = 'classicmodels'
ORDER BY 
    event_object_table , 
    action_timing , 
    event_manipulation;Code language: SQL (Structured Query Language) (sql)
MySQL Multiple Trigger example

In this tutorial, you have learned how to create multiple triggers for a table that have the same event and action time.

Was this tutorial helpful?