New as of MySQL 5.0.2 is the trigger. A trigger is an action that automatically takes place when a specific something happens to a specific table. As triggers are associated with a table, they are therefore particular to that table and database. Furthermore, since they are automatically enacted, there is no way to invoke a trigger (other than taking whatever action invokes it).
The general syntax for making a trigger is
CREATE TRIGGER trigger_name time event ON tablename FOR EACH ROW statement
The trigger_name value abides by pretty much the same rules as anything you name in MySQLdatabases, tables, column, indexes: use alphanumeric characters, plus the underscore, avoid spaces and existing keywords, and so on. For the time value, this is either BEFORE or AFTER, indicating whether the trigger should run before the event takes place or afterward. For example, say that a trigger updates Table B every time a new record is added to Table A. Should that update happen before the insertion or after?
The event value corresponds to a type of action happening to the table. The possible events are listed in Table 11.1.
Table 11.1. These three events are used in triggers. Notice that they don't apply to only INSERT, UPDATE, and DELETE queries, but rather when rows are inserted, updated, or deleted by any applicable query.
Applies When Rows Are...
Added to the table, including through LOAD DATA
Finally, the statement part of the trigger is where the real magic happens. The code here will be much like that in a stored routine, using the same control structures, BEGIN...END blocks, and types of variables. Rather than give an example here, I'll show it to you in the following steps. But first, one last concept....
A complication can arise when working with triggers, as you often end up referring to columns whose values change. To remedy this, MySQL added the OLD and NEW keywords (case-insensitive) as a way to distinguish them. Both are used in the form of OLD.columname and NEW.columname. You'll want to use OLD anytime you are referring to an existing column changed by an UPDATE or DELETE. Note that you can use OLD either BEFORE or AFTER the UPDATE or DELETE. You'll want to use NEW to refer to the content used during an INSERT or UPDATE. It's often used to change data that's being entered into the table.
For my trigger examples, I'm going to create some new tables in a new database. The premise will be an e-commerce application that sells several types of doodads. Triggers will be used to manage the inventory as doodads are ordered or as orders get canceled.
To create a trigger:
Log in to the mysql client as a user that can create new databases.
Create a new database called ecommerce
CREATE DATABASE ecommerce;
Figure 11.21. A new database will be created and used for the trigger examples.
Create the doodads
table (Figure 11.22
CREATE TABLE doodads (
doodad_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
doodad_name VARCHAR(40) NOT NULL,
doodad_price DECIMAL(10,2) UNSIGNED NOT NULL,
doodad_on_hand MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (doodad_id),
Figure 11.22. Creating the doodads table.
This is a very simple table with just four columns. No column can be NULL
, and all merit having an index placed on them. A real e-commerce application would probably have descriptions, sizes, weights, and so forth in such a table.
Create the orders table
CREATE TABLE orders (
order_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
doodad_id INT UNSIGNED NOT NULL,
PRIMARY KEY (order_id),
This table is also very simple, too simple really. Obviously in the real world there might be multiple products in an order or multiple quantities of the same product. Orders would also be associated with, you know, clients
. But I'm using just the bare-bones stuff here in order to best focus on the triggers themselves.
Figure 11.23. Creating the orders table.
Populate the doodads
table (Figure 11.24
INSERT INTO doodads VALUES
(NULL, 'a', 19.95, 20),
(NULL, 'b', 15.00, 10),
(NULL, 'c', 22.95, 5),
(NULL, 'd', 10.00, 15);
That'll be enough to demonstrate the concept. Now you can create the triggers that update the quantities in the doodads
table when an order is placed.
Figure 11.24. A few sample doodads are added to the database.
Change the delimiter.
Change the delimiter so that mysql
doesn't choke when you use semicolons in the trigger's body.
Create the INSERT
trigger (Figure 11.25
CREATE TRIGGER update_qty_insert
AFTER INSERT ON orders FOR EACH ROW
UPDATE doodads SET
To define the trigger, I start by giving it a unique name. Then I state that the trigger should take effect AFTER
a row is INSERT
ed into the orders
The trigger itself runs one UPDATE
query. The query subtracts 1 from the current doodad_on_hand
value for the item being ordered. You can refer to this new (inserted) value by using NEW.doodad_id
When you run this query:
INSERT INTO orders (doodad_id)
In the trigger, the UPDATE
query uses the submitted value (3) in the WHERE
Figure 11.25. The first trigger updates a quantity when a new order is submitted.
Create the DELETE
trigger (Figure 11.26
CREATE TRIGGER update_qty_delete
BEFORE DELETE ON orders FOR EACH ROW
UPDATE doodads SET
This trigger differs from that in Step 7 in that it takes place BEFORE
query. (Technically, however, it could take place AFTER
and still have the same effect in this particular instance.) The UPDATE
query itself uses OLD.doodad_id
to know which item was removed.
Note that the delimiter is still $$
until I change it back (in Step 9).
Figure 11.26. The second trigger updates a quantity when an existing order is cancelled (deleted).
To remove an existing trigger, simply use
DROP TRIGGER trigger_name
You can also use the more formal
DROP TRIGGER database_name.trigger_name
Note that, at the time of this writing, there is no ALTER TRIGGER command. If you need to modify a trigger, you must drop and then re-create it.
Change the delimiter back to the semicolon.
Add some items to the orders table (Figure 11.27
INSERT INTO orders (doodad_id)
VALUES (1), (2), (3), (1), (1);
Each of these inserted rows will trigger update_qty_insert
Figure 11.27. Five orders are added to the orders table. Each invokes the trigger, which in turn updates the quantities in the doodads table (see Figure 11.28).
Check the existing quantities (Figure 11.28
The results of this query should reveal how the doodad_on_hand
values have been altered for each order.
Figure 11.28. The on-hand values have been reduced in conjunction with the added records in the orders table.
Delete an order.
DELETE FROM orders WHERE order_id=4;
This will have the net effect of increasing the doodad_on_hand
value of the corresponding doodad by 1.
Recheck the existing quantities (Figure 11.29
Figure 11.29. After deleting order number 4, which was for doodad number 1, the doodad_on_hand value for that doodad is increased. Compare with Figure 11.28.
You cannot create two triggers on the same table with the same time and event. In other words, there cannot be two BEFORE INSERT or AFTER DELETE actions. If you need to do multiple things with the same time and event, just create one trigger with multiple steps in its body.
Stored routine, trigger, and view names are not case sensitive on any platform.
Triggers can call stored routines.