📖 Scenario: You manage a small online store database. You want to keep track of when product prices change by automatically recording the old price before any update.
🎯 Goal: Create a MySQL BEFORE UPDATE trigger that saves the old price of a product into a separate column before the price is updated.
📋 What You'll Learn
Create a table called products with columns id, name, price, and old_price
Add a BEFORE UPDATE trigger named before_price_update on the products table
The trigger should copy the current price value into old_price before the update happens
Test the trigger by updating a product's price
💡 Why This Matters
🌍 Real World
BEFORE UPDATE triggers help keep track of changes automatically in databases, useful for auditing and history tracking.
💼 Career
Database developers and administrators use triggers to enforce business rules and maintain data integrity without manual intervention.
Progress0 / 4 steps
1
Create the products table
Create a table called products with these columns: id as INT primary key, name as VARCHAR(50), price as DECIMAL(10,2), and old_price as DECIMAL(10,2) that can be NULL.
MySQL
Hint
Use CREATE TABLE with the exact column names and types.
2
Insert sample data into products
Insert a product into products with id 1, name 'Coffee Mug', and price 12.99. Leave old_price as NULL.
MySQL
Hint
Use INSERT INTO products (id, name, price, old_price) with the exact values.
3
Create the BEFORE UPDATE trigger
Create a BEFORE UPDATE trigger named before_price_update on the products table that sets NEW.old_price to the current OLD.price before the update.
MySQL
Hint
Use DELIMITER $$ to define the trigger, then reset delimiter after.
4
Update the product price to test the trigger
Write an UPDATE statement to change the price of the product with id 1 to 15.99. This will activate the trigger and set old_price automatically.
MySQL
Hint
Use UPDATE products SET price = 15.99 WHERE id = 1; exactly.
Practice
(1/5)
1. What is the main purpose of a BEFORE UPDATE trigger in MySQL?
easy
A. To execute code before a row is updated, allowing data validation or modification.
B. To execute code after a row is updated, for logging changes.
C. To prevent any updates on a table permanently.
D. To create a backup of the table before updating.
Solution
Step 1: Understand trigger timing
BEFORE UPDATE triggers run before the data is changed in the table.
Step 2: Purpose of the trigger
This timing allows checking or modifying the new data before it is saved.
Final Answer:
To execute code before a row is updated, allowing data validation or modification. -> Option A
Quick Check:
BEFORE UPDATE triggers run before update [OK]
Hint: BEFORE UPDATE triggers run before saving changes [OK]
Common Mistakes:
Confusing BEFORE UPDATE with AFTER UPDATE triggers
Thinking triggers prevent updates entirely
Assuming triggers create backups automatically
2. Which of the following is the correct syntax to create a BEFORE UPDATE trigger on a table named employees?
easy
A. CREATE TRIGGER before_update_employees BEFORE UPDATE ON employees BEGIN SET NEW.salary = NEW.salary * 1.1; END;
B. CREATE TRIGGER before_update_employees AFTER UPDATE ON employees FOR EACH ROW BEGIN SET NEW.salary = NEW.salary * 1.1; END;
C. CREATE TRIGGER before_update_employees BEFORE UPDATE employees FOR EACH ROW BEGIN SET NEW.salary = NEW.salary * 1.1; END;
D. CREATE TRIGGER before_update_employees BEFORE UPDATE ON employees FOR EACH ROW BEGIN SET NEW.salary = NEW.salary * 1.1; END;
Solution
Step 1: Check trigger timing and table
The syntax requires BEFORE UPDATE ON employees to specify timing and table.
Step 2: Confirm trigger body and FOR EACH ROW
The trigger must include FOR EACH ROW and a BEGIN...END block for multiple statements.
Final Answer:
CREATE TRIGGER before_update_employees BEFORE UPDATE ON employees FOR EACH ROW BEGIN SET NEW.salary = NEW.salary * 1.1; END; -> Option D
Quick Check:
Correct syntax includes BEFORE UPDATE ON and FOR EACH ROW [OK]
Hint: Use BEFORE UPDATE ON table FOR EACH ROW syntax [OK]
Common Mistakes:
Using AFTER UPDATE instead of BEFORE UPDATE
Omitting ON keyword before table name
Missing FOR EACH ROW clause
3. Given this trigger and table:
CREATE TABLE products (id INT, price DECIMAL(5,2));
CREATE TRIGGER price_check BEFORE UPDATE ON products FOR EACH ROW BEGIN
IF NEW.price < 0 THEN SET NEW.price = 0; END IF;
END;
What happens if you run:
UPDATE products SET price = -10 WHERE id = 1;
medium
A. The price is set to -10 because triggers don't change values.
B. The update fails with a syntax error.
C. The price is set to 0 because the trigger changes negative prices to zero.
D. The price remains unchanged because the trigger runs after update.
Solution
Step 1: Understand trigger logic
The trigger checks if the new price is less than 0, then sets it to 0.
Step 2: Apply update and trigger effect
Updating price to -10 triggers the BEFORE UPDATE trigger, which changes it to 0 before saving.
Final Answer:
The price is set to 0 because the trigger changes negative prices to zero. -> Option C
Quick Check:
BEFORE UPDATE can modify NEW values [OK]
Hint: BEFORE UPDATE can fix invalid data before saving [OK]
Common Mistakes:
Thinking triggers run after update
Assuming negative price is saved as is
Expecting syntax error from trigger
4. You wrote this trigger:
CREATE TRIGGER trg BEFORE UPDATE ON orders FOR EACH ROW
BEGIN
SET NEW.status = 'processed';
END;
But when updating rows, the status does not change. What is the likely problem?
medium
A. The trigger syntax is missing a delimiter change, causing a syntax error.
B. You cannot assign values to NEW in BEFORE UPDATE triggers.
C. The trigger must be AFTER UPDATE to modify data.
D. The table 'orders' does not have a 'status' column.
Solution
Step 1: Check trigger syntax requirements
MySQL requires changing the delimiter when creating triggers with BEGIN...END blocks.
Step 2: Understand effect of missing delimiter
Without changing delimiter, the trigger creation fails silently or is incomplete, so it doesn't run.
Final Answer:
The trigger syntax is missing a delimiter change, causing a syntax error. -> Option A
Quick Check:
Use DELIMITER to create triggers with BEGIN...END [OK]
Hint: Remember to change delimiter when creating triggers with BEGIN...END [OK]
Common Mistakes:
Not changing delimiter before CREATE TRIGGER
Thinking NEW cannot be assigned in BEFORE UPDATE
Assuming AFTER UPDATE is needed to modify NEW
5. You want to prevent users from lowering their account_balance in the users table. Which BEFORE UPDATE trigger code correctly enforces this rule?
hard
A. CREATE TRIGGER check_balance BEFORE UPDATE ON users FOR EACH ROW BEGIN IF NEW.account_balance < 0 THEN SET NEW.account_balance = 0; END IF; END;
B. CREATE TRIGGER check_balance BEFORE UPDATE ON users FOR EACH ROW BEGIN IF NEW.account_balance < OLD.account_balance THEN SET NEW.account_balance = OLD.account_balance; END IF; END;
C. CREATE TRIGGER check_balance AFTER UPDATE ON users FOR EACH ROW BEGIN IF NEW.account_balance < OLD.account_balance THEN SET NEW.account_balance = OLD.account_balance; END IF; END;
D. CREATE TRIGGER check_balance BEFORE UPDATE ON users FOR EACH ROW BEGIN IF NEW.account_balance > OLD.account_balance THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot increase balance'; END IF; END;
Solution
Step 1: Understand the requirement
The trigger must prevent lowering the account_balance by resetting it to the old value if decreased.
Step 2: Analyze options
CREATE TRIGGER check_balance BEFORE UPDATE ON users FOR EACH ROW BEGIN IF NEW.account_balance < OLD.account_balance THEN SET NEW.account_balance = OLD.account_balance; END IF; END; resets NEW.account_balance to OLD.account_balance if it is less, correctly preventing decrease.
Step 3: Check other options
The code that signals an error prevents increases instead of decreases. AFTER UPDATE triggers cannot modify NEW values. The code that checks if balance is negative only prevents negative values but not decreases to lower positive values.
Final Answer:
CREATE TRIGGER check_balance BEFORE UPDATE ON users FOR EACH ROW BEGIN IF NEW.account_balance < OLD.account_balance THEN SET NEW.account_balance = OLD.account_balance; END IF; END; -> Option B
Quick Check:
Use BEFORE UPDATE and compare NEW vs OLD to prevent decrease [OK]
Hint: Compare NEW and OLD values in BEFORE UPDATE to enforce rules [OK]
Common Mistakes:
Using AFTER UPDATE to modify NEW values
Signaling error for wrong condition
Only checking for negative values, not decreases
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.