All pages
Powered by GitBook
1 of 5

Loading...

Loading...

Loading...

Loading...

Loading...

Triggers

Automate actions in MariaDB Server with triggers. Learn how to create and manage triggers that execute automatically before or after data modifications, ensuring data integrity and business logic enfo

Trigger Limitations

Understand the constraints of triggers, such as the prohibition of statements that return result sets or explicitly start/commit transactions.

The following restrictions apply to triggers:

  • All of the restrictions listed in Stored Routine Limitations.

  • All of the restrictions listed in Stored Function Limitations.

  • Triggers are always executed for each row. MariaDB does not support the standard FOR EACH STATEMENT option.

  • Triggers cannot operate on any tables in the mysql, information_schema or performance_schema database.

  • Cannot return a result set.

  • The statement is not permitted, since triggers don't return any values. Use to immediately exit a trigger.

  • Triggers are not activated by actions.

  • If a trigger is loaded into cache, it is not automatically reloaded when the table metadata changes. In this case a trigger can operate using the outdated metadata.

  • By default, with row-based replication, triggers run on the master, and the effects of their executions are replicated to the slaves. It is possible to run triggers on slaves. See .

See Also

This page is licensed: CC BY-SA / Gnu FDL

SHOW TRIGGERS
  • SHOW CREATE TRIGGER

  • RETURN
    LEAVE
    foreign key
    Running triggers on the slave for Row-based events
    Trigger Overview
    CREATE TRIGGER
    DROP TRIGGER
    Information Schema TRIGGERS Table

    Triggers and Implicit Locks

    Explains how triggers can cause implicit locks on referenced tables during the execution of a statement, potentially affecting concurrency.

    A trigger may reference multiple tables, and if a LOCK TABLES statement is used on one of the tables, other tables may at the same time also implicitly be locked due to the trigger.

    If the trigger only reads from the other table, that table are read locked. If the trigger writes to the other table, it is write-locked. If a table is read-locked for reading via LOCK TABLES, but needs to be write-locked because it could be modified by a trigger, a write lock is taken.

    All locks are acquired together when the LOCK TABLES statement is issued, and released together on UNLOCK TABLES.

    Example

    Assume table1 contains the following trigger:

    Not only is table1 write locked, table2 and table3 are also write locked, due to the possible and , while table4 is read locked due to the .

    This page is licensed: CC BY-SA / Gnu FDL

    CREATE TRIGGER

    Define a trigger on a table. This statement creates a routine that automatically executes in response to INSERT, UPDATE, or DELETE events.

    Syntax

    Description

    This statement creates a new . A trigger is a named database object that is associated with a table, and that activates when a particular event occurs for the table. The trigger becomes associated with the table named

    tbl_name
    , which must refer to a permanent table. You cannot associate a trigger with a
    TEMPORARY
    table or a view.

    CREATE TRIGGER requires the TRIGGER privilege for the table associated with the trigger.

    You can have multiple triggers for the same trigger_time and trigger_event.

    For valid identifiers to use as trigger names, see Identifier Names.

    OR REPLACE

    If used and the trigger already exists, instead of an error being returned, the existing trigger is dropped and replaced by the newly defined trigger.

    DEFINER

    The DEFINER clause determines the security context to be used when checking access privileges at trigger activation time. Usage requires the SET USER privilege.

    IF NOT EXISTS

    If the IF NOT EXISTS clause is used, the trigger is created only if a trigger of the same name does not exist. If the trigger already exists, by default a warning is returned.

    trigger_time

    trigger_time is the trigger action time. It can be BEFORE or AFTER to indicate that the trigger activates before or after each row to be modified.

    trigger_event

    Multiple trigger_event events can be specified.

    Only one trigger_event can be specified.

    trigger_event indicates the kind of statement that activates the trigger. A trigger_event can be one of the following:

    • INSERT: The trigger is activated whenever a new row is inserted into the table; for example, through INSERT, LOAD DATA, and REPLACE statements.

    • UPDATE: The trigger is activated whenever a row is modified; for example, through UPDATE statements.

    • DELETE: The trigger is activated whenever a row is deleted from the table; for example, through DELETE and REPLACE statements. However, DROP TABLE and TRUNCATE statements on the table do not activate this trigger, because they do not use DELETE. Dropping a partition does not activate DELETE triggers, either.

    FOLLOWS/PRECEDES other_trigger_name

    The FOLLOWS`` other_trigger_name and PRECEDES`` other_trigger_name options support multiple triggers per action time.

    FOLLOWS adds the new trigger after another trigger, while PRECEDES adds the new trigger before another trigger. If neither option is used, the new trigger is added last for the given action and time.

    FOLLOWS and PRECEDES are not stored in the trigger definition. However, the trigger order is guaranteed to not change over time. mariadb-dump and other backup methods do not change trigger order. You can verify the trigger order from the ACTION_ORDER column in INFORMATION_SCHEMA.TRIGGERS table.

    Atomic DDL

    MariaDB supports Atomic DDL, and CREATE TRIGGER is atomic.

    MariaDB does not support Atomic DDL.

    Examples

    OR REPLACE and IF NOT EXISTS:

    See Also

    • Identifier Names

    • Trigger Overview

    • DROP TRIGGER

    • Information Schema TRIGGERS Table

    This page is licensed: GPLv2, originally from fill_help_tables.sql

    trigger
    LOCK TABLE table1 WRITE
    CREATE TRIGGER trigger1 AFTER INSERT ON table1 FOR EACH ROW
    BEGIN
      INSERT INTO table2 VALUES (1);
      UPDATE table3 SET writes = writes+1
        WHERE id = NEW.id AND EXISTS (SELECT id FROM table4);
    END;
    INSERT
    UPDATE
    SELECT

    Trigger Overview

    A comprehensive guide to triggers, explaining their execution timing (BEFORE/AFTER), supported events, and how they interact with storage engines.

    A trigger is a set of statements that run when, or are triggered by, an event that occurs on a table.

    Events

    The event can be an INSERT, an UPDATE, or a DELETE. The trigger can be executed BEFORE or AFTER

    CREATE [OR REPLACE]
        [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
        TRIGGER [IF NOT EXISTS] 
                trigger_name trigger_time {trigger_event [ OR trigger_event] [...]}
        ON tbl_name FOR EACH ROW
       [{ FOLLOWS | PRECEDES } other_trigger_name ]
       trigger_stmt;
    
    trigger time:
        BEFORE
      | AFTER
    
    trigger_event:
        INSERT
      | UPDATE [ OF column_name [, colunm_name [, ...]]
      | DELETE
    SELECT trigger_name, action_order FROM information_schema.triggers 
      WHERE event_object_table='t1';
    CREATE DEFINER=`root`@`localhost` TRIGGER increment_animal
      AFTER INSERT ON animals FOR EACH ROW 
       UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
    CREATE DEFINER=`root`@`localhost` TRIGGER increment_animal
      AFTER INSERT ON animals FOR EACH ROW
        UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
    ERROR 1359 (HY000): Trigger already exists
    
    CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER increment_animal
      AFTER INSERT ON animals  FOR EACH ROW
        UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
    Query OK, 0 rows affected (0.12 sec)
    
    CREATE DEFINER=`root`@`localhost` TRIGGER IF NOT EXISTS increment_animal
      AFTER INSERT ON animals FOR EACH ROW
        UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
    Query OK, 0 rows affected, 1 warning (0.00 sec)
    
    SHOW WARNINGS;
    +-------+------+------------------------+
    | Level | Code | Message                |
    +-------+------+------------------------+
    | Note  | 1359 | Trigger already exists |
    +-------+------+------------------------+
    1 row in set (0.00 sec)
    SHOW TRIGGERS
    SHOW CREATE TRIGGER
    Trigger Limitations
    the event. A table can have multiple triggers defined for the same event and timing combination.

    The LOAD DATA INFILE and LOAD XML statements invoke INSERT triggers for each row that is being inserted.

    The REPLACE statement is executed with the following workflow:

    • BEFORE INSERT;

    • BEFORE DELETE (only if a row is being deleted);

    • AFTER DELETE (only if a row is being deleted);

    • AFTER INSERT.

    The INSERT ... ON DUPLICATE KEY UPDATE statement, when a row already exists, follows the following workflow:

    • BEFORE INSERT;

    • BEFORE UPDATE;

    • AFTER UPDATE.

    Otherwise, it works like a normal INSERT statement.

    Note that TRUNCATE TABLE does not activate any triggers.

    Triggers and Errors

    With non-transactional storage engines, if a BEFORE statement produces an error, the statement isn't executed. Statements that affect multiple rows fail before inserting the current row.

    With transactional engines, triggers are executed in the same transaction as the statement that invoked them.

    If a warning is issued with the SIGNAL or RESIGNAL statement (that is, an error with an SQLSTATE starting with '01'), it is treated like an error.

    Creating a Trigger

    Here's a simple example to demonstrate a trigger in action. Using these two tables as an example:

    We want to increment a counter each time a new animal is added. Here's what the trigger looks like:

    The trigger has:

    • a name (in this case, increment_animal),

    • a trigger time (in this case, after the specified trigger event),

    • a trigger event (an INSERT),

    • a table with which it is associated (animals),

    • a set of statements to run (here, just the one UPDATE statement).

    AFTER INSERT specifies that the trigger runs after an INSERT. The trigger could also be set to run before, and the statement causing the trigger could be a DELETE or an UPDATE as well. You can also have multiple triggers for an action. In this case, you can use FOLLOWS | PRECEDES`` other_trigger_name to specify the order of the triggers.

    The set of statements to run are the statements on the table of the trigger; therefore, columns/values that change are always just a column name or an expression like NEW.column_name. Table references of other tables must come from explicit table references.

    Now, if we insert a record into the animals table, the trigger runs, incrementing the animal_count table.

    For more details on the syntax, see CREATE TRIGGER.

    Dropping Triggers

    To drop a trigger, use the DROP TRIGGER statement. Triggers are also dropped if the table with which they are associated is also dropped.

    Triggers Metadata

    The Information Schema TRIGGERS Table stores information about triggers.

    The SHOW TRIGGERS statement returns similar information.

    The SHOW CREATE TRIGGER statement returns a CREATE TRIGGER statement that creates the given trigger.

    More Complex Triggers

    Triggers can consist of multiple statements enclosed by a BEGIN and END. If you're entering multiple statements on the command line, temporarily set a new delimiter so that you can use a semicolon to delimit the statements inside your trigger. See Delimiters in the mariadb client for more.

    Trigger Errors

    If a trigger contains an error and the engine is transactional, or it is a BEFORE trigger, the trigger will not run, and will prevent the original statement from running as well. If the engine is non-transactional, and it is an AFTER trigger, the trigger will not run, but the original statement will.

    Here, we'll drop the above examples and then recreate the trigger with an error, a field that doesn't exist, first using the default InnoDB, a transactional engine, and then again using MyISAM, a non-transactional engine.

    And now the identical procedure, but with a MyISAM table.

    The following example shows how to use a trigger to validate data. The SIGNAL statement is used to intentionally produce an error if the email field is not a valid email. As the example shows, in that case, the new row is not inserted (because it is a BEFORE trigger).

    See Also

    • CREATE TRIGGER

    • DROP TRIGGER

    • Information Schema TRIGGERS Table

    • SHOW TRIGGERS

    • (video)

    This page is licensed: CC BY-SA / Gnu FDL

    CREATE TABLE animals (id MEDIUMINT(9) 
    NOT NULL AUTO_INCREMENT, 
    name CHAR(30) NOT NULL, 
    PRIMARY KEY (`id`));
    
    CREATE TABLE animal_count (animals INT);
    
    INSERT INTO animal_count (animals) VALUES(0);
    CREATE TRIGGER increment_animal 
    AFTER INSERT ON animals 
    FOR EACH ROW 
    UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
    SELECT * FROM animal_count;
    +---------+
    | animals |
    +---------+
    |       0 |
    +---------+
    
    INSERT INTO animals (name) VALUES('aardvark');
    INSERT INTO animals (name) VALUES('baboon');
    
    SELECT * FROM animal_count;
    +---------+
    | animals |
    +---------+
    |       2 |
    +---------+
    DROP TRIGGER increment_animal;
    DROP TABLE animals;
    
    UPDATE animal_count SET animals=0;
    
    CREATE TABLE animals (id MEDIUMINT(9) NOT NULL AUTO_INCREMENT, 
    name CHAR(30) NOT NULL, 
    PRIMARY KEY (`id`)) 
    ENGINE=InnoDB;
    
    DELIMITER //
    CREATE TRIGGER the_mooses_are_loose
    AFTER INSERT ON animals
    FOR EACH ROW
    BEGIN
     IF NEW.name = 'Moose' THEN
      UPDATE animal_count SET animal_count.animals = animal_count.animals+100;
     ELSE 
      UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
     END IF;
    END; //
    
    DELIMITER ;
    
    INSERT INTO animals (name) VALUES('Aardvark');
    
    SELECT * FROM animal_count;
    +---------+
    | animals |
    +---------+
    |       1 |
    +---------+
    
    INSERT INTO animals (name) VALUES('Moose');
    
    SELECT * FROM animal_count;
    +---------+
    | animals |
    +---------+
    |     101 |
    +---------+
    DROP TABLE animals;
    
    CREATE TABLE animals (id MEDIUMINT(9) NOT NULL AUTO_INCREMENT, 
    name CHAR(30) NOT NULL, 
    PRIMARY KEY (`id`)) 
    ENGINE=InnoDB;
    
    CREATE TRIGGER increment_animal 
    AFTER INSERT ON animals 
    FOR EACH ROW 
    UPDATE animal_count SET animal_count.id = animal_count_id+1;
    
    INSERT INTO animals (name) VALUES('aardvark');
    ERROR 1054 (42S22): Unknown column 'animal_count.id' in 'field list'
    
    SELECT * FROM animals;
    Empty set (0.00 sec)
    DROP TABLE animals;
    
    CREATE TABLE animals (id MEDIUMINT(9) NOT NULL AUTO_INCREMENT, 
    name CHAR(30) NOT NULL, 
    PRIMARY KEY (`id`)) 
    ENGINE=MyISAM;
    
    CREATE TRIGGER increment_animal 
    AFTER INSERT ON animals 
    FOR EACH ROW 
    UPDATE animal_count SET animal_count.id = animal_count_id+1;
    
    INSERT INTO animals (name) VALUES('aardvark');
    ERROR 1054 (42S22): Unknown column 'animal_count.id' in 'field list'
    
    SELECT * FROM animals;
    +----+----------+
    | id | name     |
    +----+----------+
    |  1 | aardvark |
    +----+----------+
    CREATE TABLE user (
    	id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    	first_name CHAR(20),
    	last_name CHAR(20),
    	email CHAR(100)
    )
    	ENGINE = MyISAM;
    
    DELIMITER //
    CREATE TRIGGER bi_user
      BEFORE INSERT ON user
      FOR EACH ROW
    BEGIN
      IF NEW.email NOT LIKE '_%@_%.__%' THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Email field IS NOT valid';
      END IF;
    END; //
    DELIMITER ;
    
    INSERT INTO user (first_name, last_name, email) VALUES ('John', 'Doe', 'john_doe.example.net');
    ERROR 1644 (45000): Email field is not valid
    
    SELECT * FROM user;
    Empty set (0.00 sec)
    SHOW CREATE TRIGGER
    Trigger Limitations
    Creative uses of triggers: Things you people wouldn't believe