Practical Reading Material For Triggers
Practical Reading Material For Triggers
A trigger is a set of actions that are run automatically when a specified change
operation (SQL INSERT, UPDATE, or DELETE statement) is performed on a
specified table. Triggers are useful for tasks such as enforcing business rules,
validating input data, and keeping an audit trail.
Uses of Triggers
•Faster application development. Because the database stores triggers, you do not have to
code the trigger actions into each database application.
•Global enforcement of business rules. Define a trigger once and then reuse it for any
application that uses the database.
•Easier maintenance. If a business policy changes, you need to change only the corresponding
trigger program instead of each application program.
•Improve performance in client/server environment. All rules run on the server before the result
returns.
MySQL Triggers
We assume that you are habituated with "MySQL Stored Procedures", if not you can
read our MySQL Procedures tutorial. You can use the following statements of MySQL
procedure in triggers:
•Compound statements (BEGIN / END)
•Flow-of-control statements (IF, CASE, WHILE, LOOP, WHILE, REPEAT, LEAVE, ITERATE)
•Condition declarations
•Handler declarations
A trigger is a named database object that is associated with a table, and it activates
when a particular event (e.g. an insert, update or delete) occurs for the table. The
statement CREATE TRIGGER creates a new trigger in MySQL. Here is the syntax :
Syntax:
CREATE
[DEFINER = { user | CURRENT_USER }]
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
trigger_body
trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }
Explanation:
DEFINER clause: The DEFINER clause specifies the MySQL account to be used
when checking access privileges at trigger activation time. If a user value is given, it
should be a MySQL account specified as 'user_name'@'host_name' (the same
format used in the GRANT statement), CURRENT_USER, or CURRENT_USER().
The default DEFINER value is the user who executes the CREATE TRIGGER
statement. This is the same as specifying DEFINER = CURRENT_USER explicitly.
If you specify the DEFINER clause, these rules determine the valid DEFINER user
values:
•If you do not have the SUPER privilege, the only permitted user value is your own account,
either specified literally or by using CURRENT_USER. You cannot set the definer to some other
account.
•If you have the SUPER privilege, you can specify any syntactically valid account name. If the
account does not actually exist, a warning is generated.
•Although it is possible to create a trigger with a nonexistent DEFINER account, it is not a good
idea for such triggers to be activated until the account actually does exist. Otherwise, the
behavior with respect to privilege checking is undefined.
trigger_name: All triggers must have unique names within a schema. Triggers in
different schemas can have the same name.
trigger_event: trigger_event indicates the kind of operation that activates the trigger.
These trigger_event values are permitted:
•The trigger activates whenever a new row is inserted into the table; for example, through
INSERT, LOAD DATA, and REPLACE statements.
•The trigger activates whenever a row is modified; for example, through UPDATE statements.
•The trigger activates whenever a row is deleted from the table; for example, through DELETE
and REPLACE statements. DROP TABLE and TRUNCATE TABLE statements on the table do
not activate this trigger, because they do not use DELETE. Dropping a partition does not
activate DELETE triggers, either.
tbl_name : The trigger becomes associated with the table named tbl_name, which
must refer to a permanent table. You cannot associate a trigger with a TEMPORARY
table or a view.
In the above example, there is new keyword 'NEW' which is a MySQL extension to
triggers. There is two MySQL extension to triggers 'OLD' and 'NEW'. OLD and NEW
are not case sensitive.
•Within the trigger body, the OLD and NEW keywords enable you to access columns in the rows
affected by a trigger
•In a 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.
•In a DELETE trigger, only OLD.col_name can be used; there is no new row.
A column named with OLD is read only. You can refer to it (if you have the SELECT
privilege), but not modify it. You can refer to a column named with NEW 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 used to update
a row. (Such a SET statement has no effect in an AFTER trigger because the row
change will have already occurred.)
Sample database, table, table structure, table records for various examples
Database Name: hr
Host Name : localhost
Database user : root
Password : ' '
You can write a procedure in MySQL command line tool or you can use MySQL
workbench which is an excellent front-end tool (here we have used version 5.3 CE).
Now you can write your own trigger on a specific table, see the following example :
Note: See a new text Delete Trigger has come in Add Trigger button. Clicking on this
you can delete the trigger.
Finally you can review the script once again, as there is no error, let click
on Apply button:
This the final window before finish. Let click on Finish button.
If you take a look at the schema, you will see emp_details_AINS trigger under the
emp_details table as follows:
MySQL Trigger : Example AFTER INSERT
Now insert one record in emp_details table see the records both in emp_details and
log_emp_details tables :
mysql> INSERT INTO emp_details VALUES(236, 'RABI', 'CHANDRA',
'RABI','590.423.45700', '2013-01-12', 'AD_VP', 15000, .5);
Query OK, 1 row affected (0.07 sec)
In the following example, before insert a new record in emp_details table, a trigger
check the column value of FIRST_NAME, LAST_NAME, JOB_ID and
- If there are any space(s) before or after the FIRST_NAME, LAST_NAME, TRIM()
function will remove those.
- The value of the JOB_ID will be converted to upper cases by UPPER() function.
Now insert a row into emp_details table (check the FIRST_NAME, LAST_NAME, JOB_ID
columns) :
mysql> INSERT INTO emp_details VALUES (334, ' Ana ', ' King',
'ANA', '690.432.45701', '2013-02-05', 'it_prog', 17000, .50);
Query OK, 1 row affected (0.04 sec)
Let we promote all the students in next class i.e. 7 will be 8, 8 will be 9 and so on.
After updating a single row in student_mast table a new row will be inserted in
stu_log table where we will store the current user id and a small description regarding
the current update. Here is the trigger code :
-- Full Trigger
DDL Statements
-- Note: Only CREATE TRIGGER statements are allowed
DELIMITER
$$
USE `test`
$$
CREATE
DEFINER=`root`@`127.0.0.1`
TRIGGER `test`.`student_mast_AUPD`
AFTER UPDATE
ON `test`.`student_mast`FOR EACH ROW
-- Edit trigger body code below this line. Do not edit lines above
this one
BEGIN
INSERT into stu_log VALUES (user(), CONCAT('Update Student Record
',
OLD.NAME,' Previous Class :',OLD.ST_CLASS,' Present Class
',
NEW.st_class));
END
$$
We have a table student_marks with 10 columns and 4 rows. There are data only in
STUDENT_ID and NAME columns.
mysql> SELECT * FROM STUDENT_MARKS;
+------------+------------------+------+------+------+------
+------+-------+-----------+-------+
| STUDENT_ID | NAME | SUB1 | SUB2 | SUB3 | SUB4 | SUB5
| TOTAL | PER_MARKS | GRADE |
+------------+------------------+------+------+------+------
+------+-------+-----------+-------+
| 1 | Steven King | 0 | 0 | 0 | 0 | 0
| 0 | 0.00 | |
| 2 | Neena Kochhar | 0 | 0 | 0 | 0 | 0
| 0 | 0.00 | |
| 3 | Lex De Haan | 0 | 0 | 0 | 0 | 0
| 0 | 0.00 | |
| 4 | Alexander Hunold | 0 | 0 | 0 | 0 | 0
| 0 | 0.00 | |
+------------+------------------+------+------+------+------
+------+-------+-----------+-------+
4 rows in set (0.00 sec)
Now the exam is over and we have received all subject marks, now we will update
the table, total marks of all subject, the percentage of total marks and grade will be
automatically calculated. For this sample calculation, the following conditions are
assumed :
Total Marks (will be stored in TOTAL column) : TOTAL = SUB1 + SUB2 + SUB3 +
SUB4 + SUB5
Now check the STUDENT_MARKS table with updated data. The trigger show you
the updated records in 'stu_log'.
mysql> SELECT * FROM STUDENT_MARKS;
+------------+------------------+------+------+------+------
+------+-------+-----------+-------+
| STUDENT_ID | NAME | SUB1 | SUB2 | SUB3 | SUB4 | SUB5
| TOTAL | PER_MARKS | GRADE |
+------------+------------------+------+------+------+------
+------+-------+-----------+-------+
| 1 | Steven King | 54 | 69 | 89 | 87 | 59
| 358 | 71.60 | GOOD |
| 2 | Neena Kochhar | 0 | 0 | 0 | 0 | 0
| 0 | 0.00 | |
| 3 | Lex De Haan | 0 | 0 | 0 | 0 | 0
| 0 | 0.00 | |
| 4 | Alexander Hunold | 0 | 0 | 0 | 0 | 0
| 0 | 0.00 | |
+------------+------------------+------+------+------+------
+------+-------+-----------+-------+
4 rows in set (0.00 sec)
In our 'AFTER UPDATE' example, we had two tables student_mast and stu_log.
student_mast have three columns STUDENT_ID, NAME, ST_CLASS and stu_log
table has two columns user_id and description. We want to store some information in
stu_log table after a delete operation happened on student_mast table. Here is the
trigger :
USE `test`;
DELIMITER
$$
CREATE TRIGGER `student_mast_ADEL`
AFTER DELETE ON student_mast FOR EACH ROW
-- Edit trigger body code below this line. Do not edit lines above
this one
BEGIN
INSERT into stu_log VALUES (user(), CONCAT('Update Student Record
',
OLD.NAME,' Clas :',OLD.ST_CLASS, '-> Deleted on ', NOW()));
END;
$$
•If a BEFORE trigger fails, the operation on the corresponding row is not performed.
•A BEFORE trigger is activated by the attempt to insert or modify the row, regardless of whether
the attempt subsequently succeeds.
•An AFTER trigger is executed only if any BEFORE triggers and the row operation execute
successfully.
•An error during either a BEFORE or AFTER trigger results in failure of the entire statement that
caused trigger invocation.
•For transactional tables, failure of a statement should cause a rollback of all changes
performed by the statement.
To delete or destroy a trigger, use a DROP TRIGGER statement. You must specify
the schema name if the trigger is not in the default (current) schema :
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_nam
if you drop a table, any triggers for the table are also dropped.