Jump into concepts and practice - no test required
or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Create a BEFORE Trigger in PostgreSQL
📖 Scenario: You are managing a customer database for a small business. You want to ensure that before any new customer is added, their email address is always stored in lowercase to maintain consistency.
🎯 Goal: Build a PostgreSQL BEFORE INSERT trigger that automatically converts the email field to lowercase before saving a new customer record.
📋 What You'll Learn
Create a table called customers with columns id (integer primary key), name (text), and email (text).
Create a trigger function called lowercase_email that converts the email field to lowercase.
Create a BEFORE INSERT trigger called before_insert_customers on the customers table that calls the lowercase_email function.
Ensure the trigger modifies the NEW.email value before the row is inserted.
💡 Why This Matters
🌍 Real World
Triggers help enforce data consistency automatically, such as formatting emails uniformly before saving.
💼 Career
Database triggers are common in backend development and database administration to maintain data integrity and automate tasks.
Progress0 / 4 steps
1
Create the customers table
Create a table called customers with columns id as an integer primary key, name as text, and email as text.
PostgreSQL
Hint
Use CREATE TABLE customers and define id SERIAL PRIMARY KEY, name TEXT, and email TEXT.
2
Create the trigger function lowercase_email
Create a trigger function called lowercase_email that returns a trigger and converts NEW.email to lowercase using LOWER(NEW.email). The function should return NEW.
PostgreSQL
Hint
Define a function with CREATE OR REPLACE FUNCTION lowercase_email() RETURNS trigger. Use NEW.email := LOWER(NEW.email); and RETURN NEW;.
3
Create the BEFORE INSERT trigger before_insert_customers
Create a trigger called before_insert_customers that fires BEFORE INSERT on the customers table and calls the lowercase_email function.
PostgreSQL
Hint
Use CREATE TRIGGER before_insert_customers BEFORE INSERT ON customers FOR EACH ROW EXECUTE FUNCTION lowercase_email();
4
Verify the trigger modifies NEW.email before insert
Ensure the trigger function modifies NEW.email to lowercase before the row is inserted by confirming the trigger calls lowercase_email and the function returns NEW.
PostgreSQL
Hint
Check that NEW.email is set to lowercase and RETURN NEW is present in the function, and the trigger calls this function before insert.
Practice
(1/5)
1. What is the main purpose of a BEFORE trigger in PostgreSQL?
easy
A. To run code after data is inserted or updated
B. To delete rows automatically
C. To run custom code before data is inserted or updated
D. To create new tables dynamically
Solution
Step 1: Understand trigger timing
BEFORE triggers execute before the actual data change happens in the table.
Step 2: Identify trigger purpose
They allow checking or modifying data before it is saved, preventing bad data if needed.
Final Answer:
To run custom code before data is inserted or updated -> Option C
Quick Check:
BEFORE trigger = runs before data change [OK]
Hint: BEFORE triggers run before saving data [OK]
Common Mistakes:
Confusing BEFORE with AFTER triggers
Thinking triggers create or delete tables
Assuming triggers run only after data changes
2. Which of the following is the correct syntax to create a BEFORE INSERT trigger on a table named users?
easy
A. CREATE TRIGGER trg BEFORE INSERT ON users CALL func();
B. CREATE TRIGGER trg AFTER INSERT ON users EXECUTE FUNCTION func();
C. CREATE TRIGGER trg BEFORE INSERT INTO users EXECUTE FUNCTION func();
D. CREATE TRIGGER trg BEFORE INSERT ON users EXECUTE FUNCTION func();
Solution
Step 1: Check trigger timing and event
The trigger must be BEFORE INSERT on the table users.
Step 2: Verify syntax for calling function
PostgreSQL uses EXECUTE FUNCTION to call the trigger function.
Final Answer:
CREATE TRIGGER trg BEFORE INSERT ON users EXECUTE FUNCTION func(); -> Option D
Quick Check:
Correct syntax uses BEFORE INSERT ON and EXECUTE FUNCTION [OK]
Hint: Use BEFORE INSERT ON table EXECUTE FUNCTION func() [OK]
Common Mistakes:
Using AFTER instead of BEFORE
Writing INTO instead of ON
Using CALL instead of EXECUTE FUNCTION
3. Consider this BEFORE INSERT trigger function that changes the new row's status to 'active':
CREATE FUNCTION set_status() RETURNS trigger AS $$
BEGIN
NEW.status := 'active';
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_set_status BEFORE INSERT ON accounts
FOR EACH ROW EXECUTE FUNCTION set_status();
INSERT INTO accounts (id, status) VALUES (1, 'pending');
SELECT status FROM accounts WHERE id = 1;
What will be the output of the SELECT query?
medium
A. active
B. NULL
C. pending
D. Error: cannot insert
Solution
Step 1: Understand BEFORE INSERT trigger effect
The trigger sets NEW.status to 'active' before the row is inserted.
Step 2: Check inserted data
Even though 'pending' was given, the trigger changes it to 'active' before saving.
Final Answer:
active -> Option A
Quick Check:
BEFORE trigger modifies data before insert [OK]
Hint: BEFORE triggers can modify NEW row data before insert [OK]
Common Mistakes:
Assuming original value 'pending' is saved
Thinking trigger runs after insert
Expecting NULL or error without reason
4. Given this trigger function:
CREATE FUNCTION check_age() RETURNS trigger AS $$
BEGIN
IF NEW.age < 18 THEN
RAISE EXCEPTION 'Age must be 18 or older';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
Which problem will occur if you create a BEFORE INSERT trigger using this function and try to insert a row with age = 16?
medium
A. An error will be raised and insertion will stop
B. The trigger will silently ignore the age check
C. The row will be inserted with age 16
D. The age will be automatically set to 18
Solution
Step 1: Analyze trigger logic
If NEW.age is less than 18, the trigger raises an exception.
Step 2: Understand effect of RAISE EXCEPTION
Raising an exception stops the insert and returns an error to the client.
Final Answer:
An error will be raised and insertion will stop -> Option A
Quick Check:
RAISE EXCEPTION stops insert with error [OK]
Hint: RAISE EXCEPTION in BEFORE trigger stops insert with error [OK]
Common Mistakes:
Thinking the row inserts anyway
Assuming age auto-corrects
Ignoring that exceptions stop execution
5. You want to create a BEFORE UPDATE trigger on the products table that prevents the price from being set below zero. Which trigger function code correctly enforces this rule?
hard
A.
BEGIN
IF NEW.price < 0 THEN
NEW.price := 0;
END IF;
RETURN NEW;
END;
B.
BEGIN
IF NEW.price < 0 THEN
RAISE EXCEPTION 'Price cannot be negative';
END IF;
RETURN NEW;
END;
C.
BEGIN
IF OLD.price < 0 THEN
RAISE EXCEPTION 'Price cannot be negative';
END IF;
RETURN NEW;
END;
D.
BEGIN
IF NEW.price < 0 THEN
DELETE FROM products WHERE id = NEW.id;
END IF;
RETURN NEW;
END;
Solution
Step 1: Identify correct condition check
The trigger must check NEW.price to prevent negative values before update.
Step 2: Choose proper action on invalid data
Raising an exception stops the update and prevents invalid price.
Step 3: Eliminate incorrect options
BEGIN
IF NEW.price < 0 THEN
NEW.price := 0;
END IF;
RETURN NEW;
END;
silently changes price to 0 (may hide errors), C checks OLD.price (wrong), D deletes row (not appropriate).
Final Answer:
BEGIN
IF NEW.price < 0 THEN
RAISE EXCEPTION 'Price cannot be negative';
END IF;
RETURN NEW;
END; -> Option B
Quick Check:
Use RAISE EXCEPTION on NEW.price < 0 to stop update [OK]
Hint: Raise error on NEW.price < 0 to block update [OK]