Introduction to MySQL Triggers

Introduction to MySQL Triggers

Tutorial Details
  • Program: MySQL
  • Difficulty: Intermediate
  • Completion Time: 10 Minutes

Chances are, you know what a database trigger is, at least in conceptual terms. Chances are even greater that you know that MySQL supports triggers and has supported them for quite some time. I would guess, even armed with this knowledge, that a good many of you are not taking advantage of triggers with MySQL. They’re one of those things which should absolutely be in your development toolbox, as they can really change the way that you look at your data.


Introduction: What is a Trigger

“However, as applications grow more and more complicated, the further we can abstract the layers of an application to handle what they should, the greater our internal development usability becomes.”

For the uninitiated, a trigger is a rule that you put on a table which basically says, whenever you DELETE, UPDATE or INSERT something in this table, also do something else. For instance, we might want to log a change, but instead of writing two separate queries, one for the change, and one for the log, we can instead write a trigger that says, “Whenever this row is updated, create a new row in a different table to tell me that the update was made”. It adds a little overhead to the initial query, but since there are not two packets traveling to your database to do two separate things, there is an overall performance gain (in theory anyway).

Triggers were introduced into MySQL in version 5.0.2. The syntax for a trigger is a bit foreign on first blush. MySQL uses the ANSI SQL:2003 standard for procedures and other functions. If you are comfortable with a programming language in general, it is not that difficult to understand. The specification is not freely available, so I will do my best to use simple structures and explain what is happening within the trigger. You will be dealing with the same logic structures that any programming language provides.

As I mentioned above, triggers will be executed procedurally on UPDATE, DELETE and INSERT events. What I didn’t mention is that they can be executed either before or after the event defined. Therefore, you could have a trigger that will fire before a DELETE or after a DELETE, so on and so on. This means that you could have one trigger that fires before an INSERT and a separate one that fires AFTER an INSERT, which can be very powerful.

I am going to look at three uses that you could consider adding to your toolbox. There are several uses that I will not be delving into, as I feel there are better methods to get the same results, or they deserve their own tutorial. Each of these uses that I am exploring have a counterpart in your server side logic layer, and are not new concepts. However, as applications grow more and more complicated, the further we can abstract the layers of an application to handle what they should, the greater our internal development usability becomes.


Beginnings: My Table Structure, Tools and Notes

I am working with a mythical cart system, with items that have prices. I have tried to keep the data structure as simple as possible just for illustration purposes. I am naming columns and tables for the purpose of understanding, and not for production use. I am also using TIMESTAMPS rather than other alternatives for ease. For those playing the at-home version of today’s game, I am using the table names of carts, cart_items, cart_log, items, items_cost.

Please note throughout this tutorial I will be using very simple queries to express my points. I am not binding any variable, as I am not using any user input. I want to make the queries as easy to read as possible, but don’t use this tutorial for anything other than practical trigger applications. I know there might be a comment or two about this, so consider this my disclaimer.

I am using the Particle Tree PHP Quick Profiler to see execution times. I am also using the database abstraction layer provided in the tool just for my own benefit. It’s a nice tool, and does much more than just providing SQL execution times.

I am also using Chive to illustrate the DB effects and create my triggers. Chive is MySQL 5+ only, and is very similar to PHPMyAdmin. It’s prettier, but also much buggier at the moment. I am using Chive, simply because it gives good screen shots as to what is happening with the queries.

One other quick note. You may need to change the delimiter for MySQL while creating a trigger. The natural delimiter for MySQL is ; but since we will be using that delimiter for our added queries, you may need to explicitly rename the delimiter if creating these via command line. I have chosen not to show this, because using Chive, there is no need to change the delimiter.

To change a delimiter, you would simply do this before your trigger command:

DELIMITER $$

And this after your trigger command:

DELIMITER ;

The Easy Trigger: Data Integrity

If you do even the slightest normalization to your database structure you have probably run into a time where you have deleted the main data source, but still have fragments running around in your data stream. For instance, you might have an cart_id which is referenced in two or three tables without foreign keys, particularly since foreign keys are not supported with the MyISAM engine.

What you have probably done in the past is something like this (simplified for illustration):

    $sql = 'DELETE FROM no_trigger_cart_items WHERE cart_id = 1';
    $rs = $this->db->query($sql);

    $sql = 'DELETE FROM no_trigger_carts WHERE cart_id = 1';
    $rs = $this->db->query($sql);

Now, depending on how well you organize yourself, you might have a single API or method which you would clear your carts. If that is the case, you have isolated your logic to run these two queries. If that is not the case, then you always need to remember to clear your cart items when you delete a specific cart. Not difficult, but when you forget, you are losing your data integrity.

Enter our trigger. I am going to create a very simple trigger so that whenever I delete a cart, my trigger will fire to delete any cart items that have the same cart_id:

CREATE TRIGGER `tutorial`.`before_delete_carts`
    BEFORE DELETE ON `trigger_carts` FOR EACH ROW
    BEGIN
        DELETE FROM trigger_cart_items WHERE OLD.cart_id = cart_id;
    END

Very simple syntax as I said above. Let’s go through each line.

My first line states “CREATE TRIGGER `tutorial`.`before_delete_carts`”. I am telling MySQL to create a trigger on the database “tutorial” to have a name of “before_delete_carts”. I tend to name my triggers with the formula of “When_How_Table”. That works for me, but there are plenty of other ways to do this.

My second line tells MySQL the definition of this trigger, “BEFORE DELETE ON `trigger_carts` FOR EACH ROW”. I am telling MySQL that before you delete on this table, for each row do something. That something is explained next, within our BEGIN and END. “DELETE FROM trigger_cart_items WHERE OLD.cart_id = cart_id;” I am telling MySQL before you delete from trigger_carts, take the OLD.cart_id and also delete from trigger_cart_items. The OLD Syntax is the defined variable. We will discuss this in the next section where we will combine OLD and NEW.

There is really nothing to creating this trigger. The advantage is moving your data integrity logic to your data layer, which I could make the case, is where it belongs. There is also one other slight advantage and that is the slight performance gain, seen below.

Two Queries:

Delete with No Trigger

One Query with a Trigger:

Delete with a Trigger

As you can see there is a slight performance gain, which should be expected. My database that I am using is on localhost with my server, but had I been using a separate DB server, my performance gain would be a bit greater due to round trip time between the two servers. My trigger delete has a slightly higher time to delete, but there is only one query, so the overall time decreases. Multiply this over all the code that you use to keep your data integrity, and the performance gain becomes at least modest.

One note on the performance, the first time the trigger runs, it may be much slower than subsequent times. I don’t use triggers necessarily for the performance gain, but rather to move my data logic to my data layer, just like you want to move your presentation from your markup to your presentation layer, otherwise known as CSS.


The Pretty Easy Trigger: Logging and Auditing

The next example that we will look at will deal with logging. Say I want to keep track of every item placed into a cart. Perhaps, I want to monitor my cart items purchase rate. Perhaps, I just want to have a copy of every item placed into a cart, not necessarily sold, just for some insight into the mind of my customers. Perhaps, you created your cart items as a MEMORY table, and you want to log all items in an InnoDB table. Whatever the reason, let’s look at an INSERT trigger, which will open up some good possibilities for logging or auditing of our data.

Before triggers, we probably did something like this (again, simplified for illustration):

Create with No Trigger

Now, we can create a very simple trigger for this logging process:

CREATE TRIGGER `after_insert_cart_items`
    AFTER INSERT ON `trigger_cart_items` FOR EACH ROW
    BEGIN
        INSERT INTO trigger_cart_log (cart_id, item_id)
        VALUES (NEW.cart_id, NEW.item_id);
    END

Let’s run through this again, just so there is clarity of what this trigger is doing. First we start with the line, “CREATE TRIGGER `after_insert_cart_items`”. I am again telling MySQL to create a trigger with the name of “after_insert_cart_items”. The name could be “Foo”, or “BullWinkle” or whatever you want to call it, but again, I prefer to illustrate my trigger names. Next we see, “AFTER INSERT ON `trigger_cart_items` FOR EACH ROW”. Again, this is saying after we insert something on trigger_cart_items, for each row inserted execute what is between my BEGIN and END.

Finally, we just have, “INSERT INTO trigger_cart_log (cart_id, item_id) VALUES (NEW.cart_id, NEW.item_id);” which is a standard query with the exception of my two values. I am using the NEW value that is inserted into the cart_items table.

And we have cut our queries in half with the subtle performance gain:

Create with a Trigger

And just to check that our trigger is working, I see the values in my table:

Proof of my Trigger

This is again, relatively easy, but we are working with a couple of values, which can add to the complexity just a bit. Let’s look at something a little harder.


The Harder Trigger: Business Logic

At this point we can skip the old way of multiple queries with a single query. I imagine that will get just a whee bit tedious to continue to measure performance of queries. Instead, let’s get into a few more advance examples of triggers.

Business logic is where the bugs always creep up. Regardless, of how careful or organized we are, something always slips through the cracks. Triggers on UPDATE mitigate that just a bit. We have some power in a trigger to evaluate what the OLD value was, and set the NEW value based on the evaluation. Say for instance we want to always have our price of items to be a 30% markup of the cost of the items. It makes natural sense then, that when we UPDATE our cost, we also need to UPDATE our price. Let’s handle that with a trigger.

CREATE TRIGGER `after_update_cost`
    AFTER UPDATE ON `trigger_items_cost` FOR EACH ROW
    BEGIN
       UPDATE trigger_items
       SET price = (NEW.cost * 1.3)
       WHERE item_id = NEW.item_id;
    END

What we are doing is updating the items table with a price based on the NEW.cost times 1.3. I entered a cost of $50, so my new price should be $65.

Update Trigger Price Change

Sure enough, this trigger worked as well.

We need to take a look at a bit more advanced example. We already have the rule to change the price of an item based on it’s cost. Let’s say that we want to tier our cost a bit. If the cost is less than $50 our cost is actually $50. If it the cost is over $50 but less than $100 then our cost becomes $100 dollars. While my example probably doesn’t match a true business rule, we do adjust cost based on factors everyday. I am merely trying to keep the example easy to understand.

In order to do this, we are again going to work with an UPDATE but this time we will fire it before we execute our query. We are also going to be working with an IF statement, which is available to us.

Here’s the new trigger:

CREATE TRIGGER `before_update_cost`
    BEFORE UPDATE ON `trigger_items_cost` FOR EACH ROW
    BEGIN
        IF NEW.cost < 50 THEN
            SET NEW.cost = 50;
        ELSEIF NEW.cost > 50 AND NEW.cost < 100 THEN
            SET NEW.cost = 100;
        END IF;
    END

What we are doing now is not calling a query, but rather just overriding the value. I am saying if the cost is less than $50, then just make it $50. If the cost is between $50 and $100, then make it $100. If it is above that, then I just let it stay the same. My syntax here is not that foreign from any other server side language. We do need to close our IF clause with an END IF; but other than that, it really isn't tricky.

Just to check to see if our trigger works, I have entered a value of $30 for the cost, and it should be $50:

Cost Is 50

When I enter a cost of $85, here is the value:

Cost Is 100

And, just to check if my AFTER UPDATE trigger is still working, my price should now be $130:

Price is 130

Life is good.


Conclusion

I have only touched the tip of the iceberg with triggers and MySQL. While there are countless uses for triggers, I have gotten along just fine in the past without them by dealing with my data in my logic layer. That said, the ability to add rules to my data in the data layer just makes sense. When you add in the modest performance improvements, the advantage is even greater.

We have to deal with complicated high traffic web applications now. While using a trigger on a single page vanity site might not be the best use of time and energy; a trigger on a complex web application might make the world of difference. I hope you enjoyed the examples, and please let me know what needs further explanation.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.worldcup-2010.fr marc

    Good tutorial
    thx

  • http://www.developtus.com/ Developtus

    Very nice article! I’ll try to put in practice

  • w1sh

    I hate the ungrateful jerks that comment on something because it’s not an exact solution to their current problem, but I can’t resist speaking out against all these PHP/MySQL circle-jerks.

    Sarcasm will do…

    Sweet! More PHP/MySQL tutorials! It’s a good thing those are the only languages that anyone could possibly ever want to learn!!

    BOY OH BOY!

    • RCKY

      Like you said sarcasm will do…

      Nice to hear your opinion.

    • Sid

      w1sh – what circle of jerks do you belong to?

      • Bill

        From the tone of his comment probably ROR ;)

    • http://www.antonagestam.se/ Anton Agestam

      Well I totally see your point, however, I found this particular tutorial very useful and I’ve been looking to learn these techniques for a very long time so I think this post might be the wrong one to complain about. I also think MySQL and PHP should be supported because they fit so good together and are so easy to learn.

  • RCKY

    Interesting… perhaps useful according to orm (what about other dbms?)…

  • Benabdallah

    Great man :) for french speaking guy (like me) http://www.scribd.com/doc/24488814/MySQL-Trigger-Cursors-Procedures-et-Fonction (not a translation)

  • Dejan

    Very nice article. Can’t wait for stored procedures … :))

    Thank you!

    • http://wyome.com John Cox

      I am doing some profiling in an application and working with SPs in some instances. I’ll probably do a tutorial with a real database, because smaller queries might not relay as well as it does with triggers and views.

  • http://blog.kowalczyk.cc Tomasz Kowalczyk

    I’m not very keen on using such techniques because it makes another abstraction layer that must be handled properly and distracts programmer from his goal, but still thanks for the article. If triggers are used correctly they are quite powerful tool enabling us to do more and faster.

    • http://www.freshclickmedia.com Shane

      Triggers can be a way of shooting yourself in the foot (sorry about the pun) – you do have to be careful sometimes when using them since their behaviour can lead to obfuscation.

      I’ve worked in some companies where their usage is ‘banned’ because of the problems they’ve caused. That’s a bit extreme in my opinion, since they can be powerful, but they’re best if they’re appropriate and documented.

      • http://wyome.com John Cox

        I don’t disagree with either sentiment from you are Tomasz, and I know they add some complexity. I use them for logging and data integrity, particularly with MyISAM tables which don’t have FK support. I keep them in the toolbox, and then I comment my queries when they are affected. Everything is a tradeoff. There are times when the modest performance gain doesn’t make sense. Other times, you need to squeeze what you can out of everything. Beat’s me which is right or wrong;)

        I think it is important to understand the concepts though, and to have that tool in your toolbox. Just my opinion though.

    • http://hubersen.ch hubeRsen

      completely agree.

  • Nibor

    What’s the name of the “MySQL Speed Information Tool” with the sexy GUI? *_*

  • Matt

    Good stuff, thanks for this! Triggers are new to me and you posted this at just the right time.

    How would you go about creating a trigger via PHP, including setting the delimiter? I could imagine that you’d have to run three different queries for that: Delimiter on — Trigger — Delimiter reset. Any clues on this one?

    The reason I’m asking – having to manually go into the db is not ideal in a production environment… Doing such things with an install script would make the app portable. Any experience on that one?

    Again, great tutorial!

    • http://wyome.com John Cox

      I’ve always just done them from command line, but if I am not mistaken (probably am;), you would execute them just as you would any query, with a CREATE TRIGGER foo, etc. The only thing that you may have to work out is the delimiter (see code in the introduction), but I am pretty sure that you would not need to change it (I have not tested that though).

      If you look at Chive, they just execute them like normal queries. That’s in the TriggerController.php in the controllers directory. It breaks when you use the delimiter through Chive, hence why I believe you don’t need to change it.

      Another tactic that you could take is write your triggers on your test db, and then just do a SQL dump, and then execute that on your production data.

      • Matt

        Thanks John. Dumping the DB is a great point, I think it shouldn’t be that hard to take this approach for a php install script entirely, and include triggers that way. I’ll look into it!

  • http://butenas.com Ignas

    A little bit away from article, but – what software you use to work with SQL? :)

    • Hitesh Chavda

      It’s Chive.

      • http://wyome.com John Cox

        Correct, Chive. Just be forewarned, it is Pre-1.0 software, and it is a little buggy. It’s worth keeping an eye on though.

  • http://www.dazzlecat.co.uk DazzleCat Digital Agency

    I work with MS SQL 2008, concepts are still the same though. Personally, I avoid triggers in all but a few occasions.

    In my opinion where triggers are used carry out business logic concerns is where you would be going wrong in their use!

    • http://wyome.com John Cox

      I use SQL 2005 and 2008 quite a bit, particularly when I am working with ColdFusion, and it is much easier to use triggers, and SPs than in MySQL. I believe they use the SQL2008 syntax, so it is a little different, but not much.

      Also I agree with you on business logic, and I debated long and hard on writing that section. In the end though, it is a practical use for a trigger and it does have its benefits with enforcing rules that are missed in the logic layer. I generally stick with triggers with logging and data integrity, but writing an article about triggers makes it hard to ignore some of their practical uses. I did ignore the filling a table for reporting purposes part, because that’s just lazy and there are better tools for that in my opinion;)

  • http://variable3.com/blog/ Harsha M V

    brilliant tutorials. just wondering… the triggers will it run every time like a mysql query ?

    • http://wyome.com John Cox

      Yes, every time, and they will run depending on how you have defined them. Before Insert, After Insert, Before Delete, After Delete, Before Update, After Update.

      They do not run on Selects, at least in MySQL.

      • http://www.abc.com Ashish Developer

        Hello All,

        Pls Dont mind i am disturbing you but i have a question on msql trigger in php .
        Please tell me and show how to execute mysql trigger in php script or it must in string in variable that after execute with mysql or mysqli.

        my localhost does not execute script and no show any error and warning.
        Please show any script in which mysql trigger wrote in php script .

        I am in so big trouble pls tame me out this problem Sir.

        ——————
        Thanks & Regards
        Ashish Developer

  • http://cettblogja.blogspot.com cett

    1: Why not be more triggere an event where they are guaranteed (sql interpreter to decide) do not affect each other’s running (say, be regulated in parallel or performed in a specific order)? Suppose you want to isolate the triggers on these logs, and develop the application by the application of the internal operation of the same incident for its own trigger. In this state (Section 5.1), such is not supported by MySQL. A bad point.
    2: Can not begin transaction was initiated triggers within … But certainly many cases where the application logic requires that triggers a rollback-made things necessary to live. Second bad point.
    3: The changing field can not be directly invoked (begin/after update). Currently, if the above lineup logged want to update an after-after what happened, what field is changed, then just a big mess if-es structure can be: if new.field1!=old.field1 then insert into …; if new.field2!=old.field2 then insert into …; if …. In such cases, would be very useful in directly changing (plus the calculated fields you can think of) fields in the parameter (say, an array form) for access to opportunity, failing to remain unnecessarily in the ultra-sized after-update trigger …

    sorry my english…

  • gabi

    i tried adding this trigger

    CREATE TRIGGER `before_delete_texts`
    BEFORE DELETE ON `texts` FOR EACH ROW
    BEGIN
    DELETE FROM `texts_lg` WHERE `id_texts` = OLD.`id_texts`;
    END
    ;

    but mysql returns this error:

    Error
    SQL query:

    CREATE TRIGGER `leaderteam`.`before_delete_texts` BEFORE DELETE ON `texts` FOR EACH ROW BEGIN DELETE FROM `texts_lg` WHERE `id_texts` = OLD.`id_texts`;

    MySQL said:

    #1064 – You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ” at line 4

    what have i done wrong??

    • http://wyome.com John Cox

      My guess:

      `id_texts` = OLD.`id_texts`

      should be:

      id.texts = OLD.id_texts

  • http://webphp.ru/ terkin

    What script is used at this screenshots for database browse?

  • http://createmy.com.au Dale Hurley

    If only you could trigger a call to execute a PHP file. For instance if something happens email someone. =0)

  • vetebröd

    Just wondering, how do you edit a trigger?

    • http://wyome.com John Cox

      I don’t believe there is an ALTER TRIGGER in mysql, like in most DB’s. I believe you have to DROP TRIGGER / CREATE TRIGGER. See bug 14661.

      http://bugs.mysql.com/bug.php?id=14661

  • http://www.ate5.com Jordan Walker

    Great write up on triggers and how much time savings you will gain by implementing them.

  • kkatusic

    Thx for this examples, I will now cthink about the use of triggers.

  • alvaro obyrne

    Hey : thanks for this tutorial… and the list of related tutorials is very nice too. Has someone written something upon “procedures”…

    • http://wyome.com John Cox

      I might be writing one soon. I am working with some profiling data with a small project which I am evaluating SPs vs the mysqli or PDO or a combination of the two.

      • alvaro obyrne

        Thanks for answering: looking forward for it…

  • David

    Why is the table name prefixed with the word “trigger” throughout all your examples? Like here:

    BEFORE UPDATE ON `trigger_items_cost` FOR EACH ROW

    • http://wyome.com John Cox

      No reason other than I had two duplicate data structures and for illustration purposes, one was named trigger, and the other named no_trigger. I was measuring performance between writing a trigger on one data structure, and using multiple queries on the other.

  • Zenion

    A very well structured and explaining tutorial, thank you John.

  • http://www.BertrandLirette.com Bertrand

    First time I’ve heard about this, thanks.

    However, might be because I’m new to this but, it seems like it add an abstraction layer to the code. I’d hate to have to check some MySQL Triggers to see why my INSERT / UPDATE/ DELETE are acting weird.

    Also, what happens when a trigger creates an error? Does it fails and PHP receives an error like when you pass an SQL command? If so, wouldn’t it be false info as one of the two query actually worked?

    I’m not building the next Facebook so I’ll trade those ms gains for some easier coding.

    Thanks for the tutorials thought, getting a little less dumber because of you! ;)

    • http://wyome.com John Cox

      I see where you are going, but it’s not really an abstraction layer because they lie within your DB. There is a little complexity, which is why I use them for logging and data integrity only for the most part. You do have to be consistent about their use, and comments before the query they will fire on will help you immensely.

      /* Trigger fires first to delete relevant user ids in tables xxx.xxx etc. */

      As far as failures, that is a short coming particularly on BEFORE UPDATE / DELETE / CREATE. On the AFTER commands, the query will fail before the trigger fires. Here’s a bit of an albeit hackish work around:

      http://www.brokenbuild.com/blog/2006/08/15/mysql-triggers-how-do-you-abort-an-insert-update-or-delete-with-a-trigger/

      Again, I generally use them for logging on CREATE and UPDATE and data integrity on DELETE to avoid those short comings. There’s always tradeoffs:)

  • http://www.sergeh.com Serge

    Great tutorial!

    Does anyone know how to get the name of the column that’s been updated?

    I’m trying to make an audit trail, part of the information I’m saving are the old and new values of whatever column that got updated but in order to do that I need the trigger to know which column has been updated…

    • http://wyome.com John Cox

      I think this is what you are looking for:

      “In an UPDATE trigger, you can use OLD.col_name to refer to the columns of a row before it is updated and NEW.col_name to refer to the columns of the row after it is updated.

      A column named with OLD is read only. You can refer to it (if you have the SELECT privilege), but not modify it. A column named with NEW can be referred to if you have the SELECT privilege for it. In a BEFORE trigger, you can also change its value with SET NEW.col_name = value if you have the UPDATE privilege for it. This means you can use a trigger to modify the values to be inserted into a new row or that are used to update a row.”

      http://dev.mysql.com/doc/refman/5.0/en/trigger-syntax.html

      • http://www.sergeh.com Serge

        Hey John,

        thanks for the reply but the problem is that I don’t know in advance which column gets updated.

        For example a user will update a client’s company. I need the trigger to save the column name, old value and new value of the modified column (in this case it’s company but it could be anything).

        I know I can use IF statements but I was hoping for something more elegant as well as better performance.

      • http://wyome.com John Cox

        Ah, then I would use CASE or an IF ELSEIF when NEW.col_name is not NULL do this, etc.

        Make sense? Here’s a pretty good entry that’s close to your use case I believe:

        http://rpbouman.blogspot.com/2009/12/validating-mysql-data-entry-with_15.html, but instead of errors with the validation use a query to log the audit trail.

      • http://www.sergeh.com Serge

        Thanks John, makes perfect sense!

  • http://one-shore.com Aaron

    What if you try to delete multiple items for your cart

    DELETE FROM cart WHERE cart_id > 1;

    With your trigger, it will delete all the carts, but only the cart items for the first cart_id (i.e. 2)

    • http://wyome.com John Cox

      The FOR EACH ROW statement means that the trigger will activate on each row provided.

  • Alfa

    Hi John,

    Great article and tutorial…but could you help me with this case?

    i create a trigger to prevent a single row to be deleted, let’s say I want to prevent deletion for Category.categoryName with value ‘Default’.

    here is the syntax

    CREATE TRIGGER restoreDefault AFTER DELETE ON Category
    FOR EACH ROW
    BEGIN
    IF(OLD.categoryName = ‘Default’)
    INSERT INTO Category VALUES(old.categoryID,old.categoryName,old.categoryDesc);
    END IF;
    END

    Please advice what’s wrong with the syntax..

    Regards.

    • http://wyome.com John Cox

      Is it just not doing as expected, or are you getting an error when you create it?

      • Alfa

        there’s an error..

        “..near ‘INSERT INTO Category VALUES(old.categoryID,old.categoryName,old.categoryDesc)’ at line 5 ”

        i have no idea to solve it…i’ve tried several combinations but all failed.

        this syntax below worked. This trigger will prevent all rows to be deleted which is not what i expect. I just need to filter a single row..

        CREATE TRIGGER restoreDefault AFTER DELETE ON Category
        FOR EACH ROW
        INSERT INTO Category VALUES(old.categoryID,old.categoryName,old.categoryDesc);

        Please advice..

        Regards.

      • http://wyome.com John Cox

        I am just guessing from what you posted, but the error is on your INSERT statement, so I would start by writing the insert this way:

        INSERT INTO
        Category (categoryID,
        categoryName,
        categoryDesc)
        VALUES (OLD.categoryID,
        OLD.categoryName,
        OLD.categoryDesc);

        So that you ensure that the column data is corresponds with the values. Since I don’t know your structure, I am just taking what you are showing me, but double check the column names.

        Secondly, if you are writing your trigger from terminal, make sure you are changing the delimiter, as shown in the beginning of the tutorial. Where it appears to be dying is at the first delimiter.

  • http://www.vincentghyssens.me Vincent Ghyssens

    Thanks for this cool tutorial !
    I knew something like that was possible but I did’nt knew how to do it.
    Looks really interesting, might be getting a nice place on my next projects.

  • http://devgroup.ru X-Developer

    Are you using chive?

  • Geeta

    Hi

    I am writing trigger as given below

    Create trigger deleteVendorServices after delete on vendor_services
    for each row Begin DECLARE done INT DEFAULT 0;
    Declare uid text;
    set uid= old.user_id
    Declare vc text;
    Declare allVc text;
    Declare c1 Cursor for select category_name from vendor_categories,vendor_services where vendor_services.vendor_category_id = vendor_categories.id and user_id=uid;
    CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    OPEN c1;
    REPEAT
    FETCH c1 INTO vc;
    set allvc=concat(concat(allvc,’,'),vc);
    UNTIL done END REPEAT;
    CLOSE cur1;
    update constellation_member_details set
    vendor_categories = allvc
    where user_id=old.user_id;
    end;

    However it is throwing error # 1064 which obviously a parse error , not suer what is the problem.
    Please help me here .

    Thanks in Advance

    • vikki

      geeta yaad aa ri ho tm….

  • http://www.programmingfacts.com Rakshit Patel

    Well Explained. Easier to understand by beginner. Thanks.

  • zay yar

    Is this possible to write a trigger to insert a new row to another table in another database. But Both databases are on the same domain

  • http://rishi89.com/ Hrishikesh Choudhari

    Can I run a trigger on the *same* table as the one on which I’ll be performing the insert command ?

    • mehra

      pagl h kya

  • http://rishi89.com/ Hrishikesh Choudhari

    Also, how are STORED PROCEDURES different than TRIGGERS in the MySQL world ?

  • Mario

    Can I use a trigger in a table to update, write or delete in another table in a different db but in the same host?
    The problem is I have 2 databases that share identic tables (structure and data). Should I use triggers or replication? Please, I need help with this. Great tutorial. Thank you.

  • Martin

    Thank you very much for this tutorial!!!!! this helps me a lot

  • Lior Rozen

    Really enjoyed reading this and I’m now looking forward to adding these methods to my dev toolbox.

    Thanks!

  • paslang

    I love this very well explain tutorial, our teacher in school taught only the basic mysql tables, but never been teach about such trigger..two more to go learning about basic stored procedures and view too..tnx

  • MWathi

    This is good work on triggers…triggers for dummies even. :)

    Thanks John

  • Anouar EL MOKHTARI

    Hi,

    Thank you very much for the tutorial…

    I’ am just having some questions:
    If I have the choice, is it better to use triggers instead of codding the operation in my program?
    How about the server ressources, do triggers consume lot of ressources (I speak about simple triggers to log data for example)?

    Thank you again

  • http://www.whycloudcomputing.net pro

    Nice tutorial, informative and very easy to understand. Expecting part 2 of it. Do u have any more links for triggers.

  • http://www.facebook.com/sourabh.kasliwal Sourabh Kasliwal

    nice stuff… very good for beginners

  • shaan

    fucking stuff