Using TriggersWith the basics covered, we will now look at each of the supported trigger types, and the differences between them. INSERT TRiggersINSERT triggers are executed before or after an INSERT statement is executed. Be aware of the following:
Here's an example (a really useful one, actually). AUTO_INCREMENT columns have values that are automatically assigned by MySQL. Chapter 21, "Creating and Manipulating Tables," suggested several ways to determine the newly generated value, but here is an even better solution: • Input CREATE TRIGGER neworder AFTER INSERT ON orders FOR EACH ROW SELECT NEW.order_num; • Analysis The code creates a trigger named neworder that is executed by AFTER INSERT ON orders. When a new order is saved in orders, MySQL generates a new order number and saves it in order_num. This trigger simply obtains this value from NEW.order_num and returns it. This trigger must be executed by AFTER INSERT because before the BEFORE INSERT statement is executed, the new order_num has not been generated yet. Using this trigger for every insertion into orders will always return the new order number. To test this trigger, try inserting a new order, like this: • Input INSERT INTO orders(order_date, cust_id) VALUES(Now(), 10001); • Output +-----------+ | order_num | +-----------+ | 20010 | +-----------+ • Analysis orders contains three columns. order_date and cust_id must be specified, order_num is automatically generated by MySQL, and order_num is also now returned automatically. Tip BEFORE or AFTER? As a rule, use BEFORE for any data validation and cleanup (you'd want to make sure that the data inserted into the table was exactly as needed). This applies to UPDATE triggers, too. DELETE triggersDELETE triggers are executed before or after a DELETE statement is executed. Be aware of the following:
The following example demonstrates the use of OLD to save rows about to be deleted into an archive table: • Input CREATE TRIGGER deleteorder BEFORE DELETE ON orders FOR EACH ROW BEGIN INSERT INTO archive_orders(order_num, order_date, cust_id) VALUES(OLD.order_num, OLD.order_date, OLD.cust_id); END; • Analysis Before any order is deleted this trigger will be executed. It used an INSERT statement to save the values in OLD (the order about to be deleted) into an archive table named archive_orders. (To actually use this example you'll need to create a table named archive_orders with the same columns as orders). The advantage of using a BEFORE DELETE TRigger (as opposed to an AFTER DELETE TRigger) is that if, for some reason, the order could not be archived, the DELETE itself will be aborted. Note Multi-Statement Triggers You'll notice that trigger deleteorder uses BEGIN and END statements to mark the trigger body. This is actually not necessary in this example, although it does no harm being there. The advantage of using a BEGIN END block is that the trigger would then be able to accommodate multiple SQL statements (one after the other within the BEGIN END block). UPDATE triggersUPDATE triggers are executed before or after an UPDATE statement is executed. Be aware of the following:
The following example ensures that state abbreviations are always in uppercase (regardless of how they were actually specified in the UPDATE statement): • Input CREATE TRIGGER updatevendor BEFORE UPDATE ON vendors FOR EACH ROW SET NEW.vend_state = Upper(NEW.vend_state); • Analysis Obviously, any data cleanup needs to occur in the BEFORE UPDATE statement as it does in this example. Each time a row is updated, the value in NEW.vend_state (the value that will be used to update table rows) is replaced with Upper(NEW.vend_state). More on TriggersBefore wrapping this chapter, here are some important points to keep in mind when using triggers:
|