Working With Triggers in A MySQL Database PDF
Working With Triggers in A MySQL Database PDF
Limited time! Try this guide by signing up for a Linode account (https://login.linode.com/signup?
promo=DOCSM1HUN8F5) with a $100 credit.
Sign Up Here!
Contribute on GitHub
Report an Issue (https://github.com/linode/docs/issues/new?title=Working%20with%20Triggers%20in%20a%20MySQL%20Database%20-
%20A%20Tutorial%20Proposed%20Changes&body=Link%3A https%3A%2F%2Flinode.com%2fdocs%2fdatabases%2fmysql%2fhow-to-work-with-triggers-in-mysql-
database%2f%0A%23%23%20Issue%0A%0A%23%23%20Suggested%20Fix%0A&labels=inaccurate guide) | View File (https://github.com/linode/docs/blob/master/docs/databases/mysql/how-to-work-with-
triggers-in-mysql-database/index.md) | Edit File (https://github.com/linode/docs/edit/develop/docs/databases/mysql/how-to-work-with-triggers-in-mysql-database/index.md)
A trigger is a pre-defined SQL command that is automatically executed when specific actions occur in the database. It can be fired either before or after an
INSERT , UPDATE , or DELETE event.
Triggers are mainly used to maintain software logic in the MySQL server, and they have several benefits:
They reduce client-side code and help minimize the round-trips made to the database server.
Some common use-cases of triggers include audit logging, pre-computing database values (e.g. cumulative sums), and enforcing complex data integrity and
validation rules.
How to create triggers that are executed before other database events occur.
How to create triggers that are executed after other database events occur.
https://www.linode.com/docs/databases/mysql/how-to-work-with-triggers-in-mysql-database/#prepare-the-database 1/10
10/7/2020 Working with Triggers in a MySQL Database - A Tutorial | Linode
How to delete triggers.
1. A configured Linode server. You can learn how to create and setup a Linode server by reading our Getting Started with Linode (/docs/getting-started/)
guide.
2. A MySQL server and client installed on the Linode server. Installation guides for MySQL are available for different distributions in our MySQL section
(/docs/databases/mysql/).
mysql -u root -p
Then, enter the root password of your MySQL server and hit Enter to proceed.
2. Next, you will see a MySQL prompt similar to the one shown below:
mysql >
Output:
USE test_database;
Output:
Database changed
5. Once the database is selected, we will create some tables that we will use for demonstrating triggers. We will begin by creating the stores table. This
table will hold information about two sample stores/offices where our hypothetical business operates from:
Output:
6. Next, add two records to the stores table by running the commands below:
https://www.linode.com/docs/databases/mysql/how-to-work-with-triggers-in-mysql-database/#prepare-the-database 2/10
10/7/2020 Working with Triggers in a MySQL Database - A Tutorial | Linode
Output:
+----------+--------------+
| store_id | store_name |
+----------+--------------+
| 1 | Philadelphia |
| 2 | Galloway |
+----------+--------------+
2 rows in set (0.01 sec)
8. Next, create the products table. The table will hold different products being offered in the store:
Output:
INSERT INTO products (product_name, cost_price, retail_price, availability) VALUES ('WIRELESS MOUSE', '18.23', '30.25','ALL');
INSERT INTO products (product_name, cost_price, retail_price, availability) VALUES ('8 MP CAMERA', '60.40', '85.40','ALL');
INSERT INTO products (product_name, cost_price, retail_price, availability) VALUES ('SMART WATCH', '189.60', '225.30','LOCAL');
You will get the output shown below after each insert command:
10. Confirm if the products were inserted by running the command below:
Output:
+------------+----------------+------------+--------------+--------------+
| product_id | product_name | cost_price | retail_price | availability |
+------------+----------------+------------+--------------+--------------+
| 1 | WIRELESS MOUSE | 18.23 | 30.25 | ALL |
| 2 | 8 MP CAMERA | 60.4 | 85.4 | ALL |
| 3 | SMART WATCH | 189.6 | 225.3 | LOCAL |
+------------+----------------+------------+--------------+--------------+
3 rows in set (0.00 sec)
11. Next, the products’ availability will be mapped to another table named products_to_stores . This table will just reference the product_id from the
products table and the store_id from the stores table where the item is available.
https://www.linode.com/docs/databases/mysql/how-to-work-with-triggers-in-mysql-database/#prepare-the-database 3/10
10/7/2020 Working with Triggers in a MySQL Database - A Tutorial | Linode
Output:
12. Next, we will create an archived_products table. The table will hold information about deleted products for future reference:
Output:
13. Lastly, we will create a products_price_history table for tracking the different prices of each product over time:
Output:
Once our database structure is in place, we can now go ahead and learn the basic syntax of a MySQL database trigger in order to create our first sample.
Trigger Syntax
As indicated earlier, triggers are fired automatically either before or after an SQL command is run in the database. The basic syntax for creating triggers is
as follows:
TRIGGER_TIME TRIGGER_EVENT
[TRIGGER BODY];
TRIGGER_NAME : Each trigger must have a unique name and you should define it here.
TRIGGER_EVENT : You need to specify the database event that will invoke the trigger: INSERT , UPDATE , or DELETE .
TRIGGER BODY : This specifies the actual SQL command (or commands) that you want to be run by your trigger.
If a trigger body has more than one SQL statement, you must enclose it within a BEGIN...END block. As well, you will need to temporarily change the
DELIMITER that signals the end of the trigger body to a new value. This ensures that the statements within the body are not prematurely interpreted by your
MySQL client. An example of this looks like the following:
DELIMITER &&
TRIGGER_TIME TRIGGER_EVENT
BEGIN
[TRIGGER BODY]
END &&
DELIMITER ;
https://www.linode.com/docs/databases/mysql/how-to-work-with-triggers-in-mysql-database/#prepare-the-database 4/10
10/7/2020 Working with Triggers in a MySQL Database - A Tutorial | Linode
Note
The last line of this example changes the DELIMITER back to the default ; value.
1. While still on the mysql > prompt, enter the command below:
DELIMITER $$
BEFORE INSERT
IF NEW.cost_price>=NEW.retail_price
THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Retail price must be greater than cost price.';
END IF $$
DELIMITER ;
The above code defines the trigger name ( price_validator ), time ( BEFORE ), event ( INSERT ), and the table ( products ) to be affected.
Our trigger uses the NEW keyword to check the cost_price and retail_price before a record is inserted to the products table, using the
IF...THEN...END IF statement.
If the cost_price is greater or equal to the retail price , our triggers tells MySQL to throw a custom exception instructing the user to rectify the
error.
2. To test the trigger above, try inserting a product that violates the validation rule:
INSERT INTO products (product_name, cost_price, retail_price, availability) VALUES ('GAMING MOUSE PAD', '145.00', '144.00','LOCAL');
Output:
ERROR 1644 (45000): Retail price must be greater than cost price.
The above insert commands should fail because the retail_price (144.00) is not greater than the cost_price (145.00).
DELIMITER $$
BEFORE UPDATE
IF NEW.product_name<>OLD.product_name
THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Product name is read-only and it can not be changed.';
END IF $$
DELIMITER ;
https://www.linode.com/docs/databases/mysql/how-to-work-with-triggers-in-mysql-database/#prepare-the-database 5/10
10/7/2020 Working with Triggers in a MySQL Database - A Tutorial | Linode
This trigger compares the values of the new product_name ( NEW.product_name ) and the old name already in the database ( OLD.product_name ). If there is
a mismatch, an exception is thrown.
2. To invoke the product_name_validator trigger, we can attempt to update the name of the product with the ID 1 :
Output:
ERROR 1644 (45000): Product name is read-only and it can not be changed.
DELIMITER $$
BEFORE DELETE
IF OLD.availability='ALL'
THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'The product can not be deleted because it is available in ALL stores.';
END IF $$
DELIMITER ;
This trigger will prevent products marked with a value of ALL in the availability column from being deleted.
2. Next, try to delete the first product from the products table and see if the trigger will be invoked:
Output:
ERROR 1644 (45000): The product can not be deleted because it is available in ALL stores.
We have looked at the different triggers that are invoked before a database operation. Next, we will look into the other types of triggers that are fired after
database events.
1. Run the code below to create the product_availability trigger. Since we have multiple lines of code in the trigger body, we will use a BEGIN...END
block:
https://www.linode.com/docs/databases/mysql/how-to-work-with-triggers-in-mysql-database/#prepare-the-database 6/10
10/7/2020 Working with Triggers in a MySQL Database - A Tutorial | Linode
DELIMITER $$
AFTER INSERT
BEGIN
IF NEW.availability='LOCAL' then
ELSE
END IF;
END $$
DELIMITER ;
When an item is being inserted into the products table, the trigger will check the availability field.
If it is marked with the LOCAL value, the product will be made available in one store only.
Any other value will instruct the trigger to make the product available to the two stores that we created earlier.
2. To see the product_availability trigger in action, insert the two records to the products table:
INSERT INTO products (product_name, cost_price, retail_price, availability) VALUES ('BLUETOOTH KEYBOARD', '17.60', '23.30','LOCAL');
INSERT INTO products (product_name, cost_price, retail_price, availability) VALUES ('DVB-T2 RECEIVE', '49.80', '53.40','ALL');
+--------+------------+----------+
| ref_id | product_id | store_id |
+--------+------------+----------+
| 1 | 4 | 1 |
| 2 | 5 | 1 |
| 3 | 5 | 2 |
+--------+------------+----------+
3 rows in set (0.00 sec)
AFTER UPDATE
INSERT INTO products_price_history (product_id, price_date, retail_price) VALUES (OLD.product_id, NOW(), NEW.retail_price);
Note
Unlike previous examples, this trigger only has one statement in the trigger’s body, so we do not need to change the DELIMITER .
2. Then, try updating the price of the first product by running the command below:
3. Next, query the products_price_history table to see if the price change was logged:
https://www.linode.com/docs/databases/mysql/how-to-work-with-triggers-in-mysql-database/#prepare-the-database 7/10
10/7/2020 Working with Triggers in a MySQL Database - A Tutorial | Linode
If the trigger worked as expected, you should get the below output:
+------------+---------------------+--------------+
| product_id | price_date | retail_price |
+------------+---------------------+--------------+
| 1 | 2020-01-28 11:46:21 | 36.75 |
+------------+---------------------+--------------+
1 row in set (0.00 sec)
AFTER DELETE
INSERT INTO archived_products (product_id, product_name, cost_price, retail_price, availability) VALUES (OLD.product_id, OLD.product_name, OLD.cost_pri
This trigger archives deleted products in a separate table named archived_products . When an item is deleted from the main products table, our trigger
will automatically log it to the archived_products table for future reference.
2. Next, delete a product from the products table and see if the trigger will be invoked:
3. Now, if you check the archived_products table, you should see one record:
Output:
+------------+--------------+------------+--------------+--------------+
| product_id | product_name | cost_price | retail_price | availability |
+------------+--------------+------------+--------------+--------------+
| 3 | SMART WATCH | 189.6 | 225.3 | LOCAL |
+------------+--------------+------------+--------------+--------------+
1 row in set (0.00 sec)
Deleting a Trigger
You have seen the different types of triggers and how they can be used in a production environment. Sometimes, you may want to remove a trigger from the
database.
You can delete a trigger if you don’t want to use it anymore using the syntax below:
Note
The IF EXISTS keyword is an optional parameters that only deletes a trigger if it exists.
For example, to delete the product_archiving trigger that we defined above, use the below command:
Output:
Caution
Be cautious when deleting tables associated with triggers. Once a table is dropped from the MySQL database, the related triggers are also automatically deleted.
https://www.linode.com/docs/databases/mysql/how-to-work-with-triggers-in-mysql-database/#prepare-the-database 8/10
10/7/2020 Working with Triggers in a MySQL Database - A Tutorial | Linode
https://www.linode.com/docs/databases/mysql/how-to-work-with-triggers-in-mysql-database/#prepare-the-database 10/10
10/7/2020 Working with Triggers in a MySQL Database - A Tutorial | Linode
More Information
You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please
note that we cannot vouch for the accuracy or timeliness of externally hosted materials.
LOG IN WITH
Name
(https://www.linode.com/)
(https://www.linode.com/)
© 2020 All rights reserved.
https://www.linode.com/docs/databases/mysql/how-to-work-with-triggers-in-mysql-database/#prepare-the-database 9/10