MySQL Triggers Tutorial

September 14, 2006 – 2:34 pm

If you’ve worked with any of the commerical databases other than MySQL, you may have already had some experience with triggers.

I’m glad that the MySQL developers finally managed to squeeze in this extremely important feature. I no longer dread trying to defend MySQL from the Microsoft and Oracle developers who have had triggers for so many years.

I’ll use the example off the MySQL website (explained below in detail). I’ll assume you know how to create a table. If not, please read up on that first.

CREATE TABLE test1(a1 INT);
CREATE TABLE test2(a2 INT);
CREATE TABLE test3(a3 INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE test4(
a4 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
b4 INT DEFAULT 0
);

DELIMITER |

CREATE TRIGGER testref BEFORE INSERT ON test1
FOR EACH ROW BEGIN
INSERT INTO test2 SET a2 = NEW.a1;
DELETE FROM test3 WHERE a3 = NEW.a1;
UPDATE test4 SET b4 = b4 + 1 WHERE a4 = NEW.a1;
END;
|

DELIMITER ;

First, we need to change the end of line delimiter. We do this because the statements in the trigger need to end in a semicolon, this is explained further below.  This is simple:

DELIMITER |

Next, we specify the action and table for this trigger. In this example, the table is “test1″, and the trigger will execute before any inserts.

CREATE TRIGGER testref BEFORE INSERT ON test1

We specify the following line to make sure if we’re doing a batch update it’ll apply the trigger to each row inserted.

FOR EACH ROW BEGIN

Now we can specify the actions that will occur as the trigger. We use the keywords NEW and OLD to reference the columns in the row. On an INSERT, there are no OLD columns.

INSERT INTO test2 SET a2 = NEW.a1;
DELETE FROM test3 WHERE a3 = NEW.a1;
UPDATE test4 SET b4 = b4 + 1 WHERE a4 = NEW.a1;

We’re done – end the trigger. To finish this single statement (because this entire trigger is really 1 statement, remember we changed our end of statement delimiter) we end it with the |

END;
|

We can now change back the end of line delimiter to a semi-colon.

DELIMITER ;

You will now have a trigger on the table ‘test1′ that occurs on every insert.

A few notes:
As of MySQL 5, triggers on DELETES will not run if you delete via cascading foreign keys.
On an INSERT, you can only use NEW for column values. On a DELETE, you must use OLD.

I will post another tutorial soon on the practical use of triggers in web development. I hope this helps someone.

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  1. 34 Responses to “MySQL Triggers Tutorial”

  2. Good job! i always wanted to know how this stuff.

    By Sunny on Sep 15, 2006

  3. I’d love to see this article on http://www.eioba.com

    By Riki on Sep 19, 2006

  4. i want to be reset a table at one hour (and a day) how can i do this

    By fatih akkoyun on Sep 19, 2006

  5. You can reset a table using cron jobs. i am assuming you are simply asking for truncating a table automatically.

    By Sunny on Sep 19, 2006

  6. its not working for me, when i place semicolin at the end of statment it terminates the mysql prompt giving error. mysql version 5.0.18. cam someone help

    By mateen on Oct 2, 2006

  7. You need to use

    DELIMITER |

    at the beginning, so the semicolons don’t end the statement.

    By jon on Oct 2, 2006

  8. yes i want this –>truncating a table automatically

    trigger can’t do or i can’t did with trigger

    so what is the cron jobs

    By fatih akkoyun on Oct 12, 2006

  9. “I’m glad that the MySQL developers finally managed to squeeze in this extremely important feature. I no longer dread trying to defend MySQL from the Microsoft and Oracle developers who have had triggers for so many years.”

    Yes triggers are nice. But if you dont know what you are doing, you can cause MAJOR overhead on your server. Ive been working with mysql 3.23.55 for a while (based on our business model upgrading is a slow process). So when you are trying to defend mysql from the evil empires, Keep in mind that they are trying to sell more licenses for servers and they will always tell you to use them.

    By Chuck on Jan 2, 2007

  10. Hi,

    I created a create database script with create table and lots of insert statements inside. At the end of the file I added the create procedure and create trigger statements using the delimiter $$ statement, but when I try to run the batch with mysql -uroot -pxxx -e “source createdb.sql”, the batch fails at the first delimiter statement. Also want to mention, that the statements are working from mysql monitor client.
    If I dump my database with triggers and strored procedures it will be filled with a lot of /*50003 CREATE */ style comments, which are working but makes the code unreadable and hard to maintain.
    If you know how to include the Create Trigger statements into a large sql file and make them work, please let me know.
    Thanks.

    By Csaba on Feb 28, 2007

  11. Thanks a lot!

    By JP on Mar 21, 2007

  12. I understand the basics of triggers, but is this a certain programming language? I would like to know what syntax the triggers use so I can make more complex triggers.

    By Travis on Mar 22, 2007

  13. hi there.will like to know how to capture the response, using php,generated by the triggers.is there exists such a way because most of the time we dont connect directly but using some other language

    By ashu on Apr 22, 2007

  14. Triggers do not produce a response, or any have any output.

    By jon on Jun 3, 2007

  15. Jon, Ashu,

    Triggers can be used to generate an output. You can include a SELECT statment in your trigger, either as a simple string

    SELECT “Task Completed”;

    or a more complex table query

    SELECT * FROM `my_tbl` WHERE `my_tbl.date`

    By Dan on Jun 5, 2007

  16. Be careful. Adding triggers in MySQL (as of 5.1) causes huge overhead and will slow performance to a point that is untenable for most moderate traffic servers. Having a feature is one thing, having a feature that performs like other DBs is quite another.

    By Erick on Aug 9, 2007

  17. thank u …thank u for letting me know the basics of triggers…regarding their creation…..syntax….working and all…..looking forward for another tutorial post!!….

    By Sri harsha on Oct 5, 2007

  18. I am new to triggers and get the syntax but have a hard time applying this knowledge!!
    I have a an auction database, and i need to write a trigger that verifies that the next bid placed is larger than the current high bid. Can anyone help me?

    By Ewa on Nov 9, 2007

  19. Hey Ewa:

    You’re probably going to want to use a stored procedure to check that. According to the MySQL boards, there’s no clean way to abort a query in mysql using a trigger. Read through this thread for more info:

    http://forums.mysql.com/read.php?99,55108,55108#msg-55108

    By jon on Dec 2, 2007

  20. Hey Everyone…

    I’ve been searching all over for the answer to this one. If you have the answer, it would help me out a lot!

    Using MySQL triggers, I want to sync content between two tables; I have table “user” and table “users”, each have similar columns “last_name” “first_name” “user_id” …etc, and when a row gets written to table “users”, I wanted that record to be replicated to “user”.

    How do I write this trigger? I know, it’s anti-normalization, but it will really help me out in the long run.

    Thanks all!

    By Ryan on Dec 20, 2007

  21. Hey Ryan

    In this case, I’d recommend calling a stored procedure to perform this type of replication.

    – almost identical tables. copying data from user to users
    create table user (userid int auto_increment primary key, fname varchar(10), lname varchar(10));
    create table users (userid int primary key, fname varchar(10), lname varchar(10));

    delimiter |
    create procedure copy_row(uid int)
    begin
    INSERT INTO users (userid, fname, lname)
    SELECT userid, fname, lname from user WHERE userid = uid;
    end;
    |
    delimiter ;

    mysql> insert into user (fname, lname) values (’joe’, ’smith’), (’steve’, ‘brown’),(’jon’, ‘haddad’);
    Query OK, 3 rows affected (0.01 sec)
    Records: 3 Duplicates: 0 Warnings: 0

    mysql> call copy_row(1);
    Query OK, 1 row affected (0.01 sec)

    mysql> select * from user;
    +——–+——-+——–+
    | userid | fname | lname |
    +——–+——-+——–+
    | 1 | joe | smith |
    | 2 | steve | brown |
    | 3 | jon | haddad |
    +——–+——-+——–+
    3 rows in set (0.00 sec)

    mysql> select * from users;
    +——–+——-+——-+
    | userid | fname | lname |
    +——–+——-+——-+
    | 1 | joe | smith |
    +——–+——-+——-+
    1 row in set (0.00 sec)

    If you really want to do this with a trigger, you can do something like this:

    delimiter |
    create trigger user_ins AFTER insert on user
    for each row begin
    call copy_row(NEW.userid);
    end;
    |
    create trigger user_upd AFTER update on user
    for each row begin
    call copy_row(NEW.userid);
    end;
    |
    create trigger user_del AFTER delete on user
    for each row begin
    delete from users WHERE userid = OLD.userid;
    end;
    |
    delimiter ;

    mysql> insert into user (fname, lname) values (’octavious’, ‘jones’);
    Query OK, 1 row affected (0.00 sec)

    mysql> select * from users;
    +——–+———–+——-+
    | userid | fname | lname |
    +——–+———–+——-+
    | 1 | joe | smith |
    | 4 | octavious | jones |
    +——–+———–+——-+
    2 rows in set (0.00 sec)

    Hopefully this helps.

    By jon on Dec 21, 2007

  22. Is it possible to generate emails with triggers? for example if a user is added to a database that the admin gets an email with the userdata? (I know this can easily be done with PHP, but I want to know if it can be done with triggers in MySQL.

    By Raymond on Apr 9, 2008

  23. To my knowledge, MySQL cannot send out emails. This question was brought up on the MySQL list in 2005, found here: http://forums.mysql.com/read.php?99,33635,33651#msg-33651

    I believe it is possible in Postgres.

    By jon on Apr 11, 2008

  24. mysql> delimiter ;
    mysql> delimiter //
    mysql> create procedure mostrar1(prov varchar(15))
    -> begin
    -> select p.id_producto,p.des_producto,pr.des_proveedor
    -> from tb_producto p,tb_proveedor pr where p.id_proveedor=pr.id_proveedor;
    -> end
    -> //

    delimiter ;
    call mostrar1();

    By ketty on Jun 13, 2008

  25. how to trigger between two database??

    By Dio on Nov 10, 2008

  26. Dio:

    If you’re talking about 1 machine with multiple schemas: did you try prefixing the database name before your table?

    If you’re talking about 2 different database servers, I don’t think you can do that with MySQL.

    By jon on Nov 11, 2008

  27. Hi, very good explanation of all the examples and theory you give to the folk. Thank you for the good job.

    I have a question that I cannot resolve yet and I hope you can help me out.

    I’m using MySQL 5.1.29 RC and I wrote a database with some tables one of them is called “users”. I want to create a trigger before insert on the table “login”. ie. before inserting any value in the table “login” I want to insert some values in another table called “users”, my code is below:

    First I created my tables with the following syntax:

    create users
    (
    userID int unsigned not null auto_increment primary key,
    company char(50)
    )type=innodb;

    create login
    (
    userID int unsigned not null,
    username char(100),
    password char(100) not null unique
    )type=innodb;

    After That I created the trigger:

    create triger test_trg before insert on login
    for each row begin
    insert into users values(NULL,’ ‘);
    end;

    result: it doesn’t work, I have tried using also those syntaxes:

    create triger test_trg before insert on login
    for each row begin
    insert into users values(’0′,’ ‘);
    end;

    create triger test_trg before insert on login
    for each row begin
    insert into users values(0);
    end;

    create triger test_trg before insert on login
    for each row begin
    insert into users set userID = ‘0′;
    insert into users set company = ’somecmpy’;
    end;

    create triger test_trg before insert on login
    for each row begin
    insert into users set userID = 0;
    insert into users set company = ’somecmpy’;
    end;

    Result: I couldn’t create my trigger yet.

    Again:
    I want to create a trigger before insert on the table “login”. ie. before inserting any value in the table “login” I want to insert a new value “userID” for the table “users”. Can you give me any clue about the problem. Thanks in advance.

    By Alexei Larramendi on Dec 1, 2008

  28. I just followed above article and is help ful to me. I m first time using trigger, it is perfect article for a bigainer.

    By Arun Patjosy on Jan 5, 2009

  29. Hey Everyone…

    I’ve been searching all over for the answer to this one. If you have the answer, it would help me out a lot!

    Using MySQL triggers for SMS Gateway, I have table “inbox” and table “voting”, I want to input table “voting” automatictly whenever SMS come (store in table inbox)I try to creat script and try to sens messange like this “man 5 3 4 10 20 30 40 50 60 70 80 90 100 11 22″:

    CREATE TRIGGER smsin AFTER INSERT ON inbox
    FOR EACH ROW
    $row = array(”TextDecoded”);
    $cut=explode(” “,$row);

    if ($cut[1]=’man’)
    {
    $query = mysql_query (”insert into voting1 values
    (’ ‘,’$cut1[0]‘,’$cut1[1]‘,’$cut1[2]‘,’$cut1[3]‘,’$cut1[4]‘,
    ‘$cut1[5]‘,’$cut1[6]‘,’$cut1[7]‘,’$cut1[8]‘,’$cut1[9]‘,
    ‘$cut1[10]‘,’$cut1[11]‘,’$cut1[12]‘,’$cut1[13]‘,’$cut1[14]‘,’$cut1[15]‘,’$cut1[16]‘)”);
    }
    else
    {
    $query = mysql_query (”insert into voting2 values
    (’ ‘,’$cut1[0]‘,’$cut1[1]‘,’$cut1[2]‘,’$cut1[3]‘,’$cut1[4]‘,
    ‘$cut1[5]‘,’$cut1[6]‘,’$cut1[7]‘,’$cut1[8]‘,’$cut1[9]‘,
    ‘$cut1[10]‘,’$cut1[11]‘,’$cut1[12]‘,’$cut1[13]‘,’$cut[14]‘)”);
    }

    Buat it didn’t run… could anybody can help ?
    I Really appreciate.

    Thanks all!

    By Dani Yusuf on Feb 1, 2009

  30. Hey, everyone
    Can you help me?
    I have problem. I have trigger that definer is my own create. When i disable my own create, my trigger is error. I want alter my trigger with other definer that I must not drop it then recreate.

    By cruise on Mar 3, 2009

  31. hi. i have a question. how to ALTER TABLE in CREATE TRIGGER? i want to ADD ROW in TABLE
    for example:
    ALTER TABLE `faqs` ADD ‘question_’+NEW.code INT NOT NULL;
    ALTER TABLE `faqs` ADD ‘answer_’+NEW.code INT NOT NULL;

    By tsogoo on Jun 22, 2009

  32. Thanks for the tutorial. Haven’t worked much with triggers and this was helpful.

    By shaun on Sep 24, 2009

  33. Thank you so much for explaining this, i never properly read the docs. Have been using oracle too much.

    By Crisitan on Feb 21, 2010

  1. 2 Trackback(s)

  2. Sep 20, 2006: davidgagne.net
  3. Jun 18, 2009: Mysql Trigger Tutorial and Tools | Learning On Demand

Post a Comment