What if you want the database to Automatically do something whenever a specific event happens? For example: "When a user is deleted, automatically copy their record to an 'Audit_Archive' table." This is the role of a Trigger.
Trigger: A named database object that is associated with a table and activates (fires) when a particular event (INSERT, UPDATE, or DELETE) occurs for that table.
- Audit Logging: Recording who changed what value and when.
- Data Consistency: Ensuring that if the
Stockin theProductstable changes, theOrderstable remains valid. - Automated Calculation: Updating a "Total Balance" column every time a "Transaction" is added.
A trigger is defined by its Timing and its Event:
| Timing | Event | Typical Use Case |
|---|---|---|
| BEFORE | INSERT |
Validating data before it reaches the table. |
| AFTER | INSERT |
Updating a summary table or audit log. |
| BEFORE | UPDATE |
Capturing the "Old Color" before it changes. |
| AFTER | UPDATE |
Syncing data to another system. |
| BEFORE | DELETE |
Checking if the deletion is allowed. |
| AFTER | DELETE |
Moving the record to an archive. |
Inside a trigger, you have access to two special virtual rows:
OLD: The row data before the change (available inUPDATEandDELETE).NEW: The row data after the change (available inINSERTandUPDATE).
DELIMITER //
CREATE TRIGGER before_salary_update
BEFORE UPDATE ON Employees
FOR EACH ROW
BEGIN
-- If the new salary is lower than old, throw error
IF NEW.Salary < OLD.Salary THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Salary cannot decrease!';
END IF;
END //
DELIMITER ;A trigger executes within the same transaction as the statement that fired it.
- User runs
UPDATE Employees. - MySQL locks the row.
- The
BEFORE UPDATEtrigger fires. - The actual
UPDATEhappens. - The
AFTER UPDATEtrigger fires. - The transaction commits.
Senior Insight: Because it's in the same transaction, if a trigger fails, the main statement also fails and rolls back.
The Audit Log Pattern:
CREATE TRIGGER audit_product_change
AFTER UPDATE ON Products
FOR EACH ROW
BEGIN
INSERT INTO Product_Log(Prod_ID, Old_Price, New_Price, Change_Time)
VALUES (OLD.ID, OLD.Price, NEW.Price, NOW());
END //- Recursive Triggers: Creating a trigger on Table A that updates Table A... which fires the trigger again... and again. This will cause an error or a crash.
- Performance: Triggers run for every single row being updated. If you update 1 million rows, the trigger runs 1 million times. Too many triggers can slow down your database significantly.
Implicit Logic Danger:
Triggers are "Silent." A developer might run an UPDATE and be confused why a value in another table also changed. Pro-Tip: Document your triggers clearly. Many teams prefer putting logic in Stored Procedures because they are "Explicit" (you have to call them) rather than "Silent."
- Task 1: What is the difference between the
OLDandNEWkeywords in a trigger? - Task 2: Write a trigger
after_user_insertthat inserts a welcome message into aNotificationstable whenever a new user is added to theUserstable.