A row-level trigger is a database feature that runs a specified action automatically for each row affected by an insert, update, or delete operation.
Click to reveal answer
beginner
Why use row-level triggers for audit logs?
Row-level triggers help automatically record changes to each row in a table, making it easy to track who changed what and when for audit purposes.
Click to reveal answer
intermediate
In Supabase, what language is used to write row-level triggers?
Supabase uses PostgreSQL, so row-level triggers are written in PL/pgSQL, a procedural language for PostgreSQL.
Click to reveal answer
intermediate
What is a common structure of an audit log table for row-level triggers?
An audit log table usually includes columns like operation type (insert, update, delete), timestamp, user ID, old data, and new data to track changes clearly.
Click to reveal answer
advanced
How does a row-level trigger capture the user who made the change in Supabase?
Supabase uses session variables or JWT claims to identify the user, which can be accessed inside the trigger function to record the user ID in the audit log.
Click to reveal answer
What does a row-level trigger execute on?
AThe entire table at once
BEach row affected by a data change
COnly the first row of a table
DOnly when the database starts
✗ Incorrect
Row-level triggers run once for every row affected by an insert, update, or delete.
Which language is used to write triggers in Supabase?
ASQL Server T-SQL
BJavaScript
CPython
DPL/pgSQL
✗ Incorrect
Supabase uses PostgreSQL, so triggers are written in PL/pgSQL.
What is NOT typically stored in an audit log table?
AUser ID who made the change
BTimestamp of the change
CThe database server version
DOld and new row data
✗ Incorrect
Audit logs focus on change details, not server version info.
How can a trigger identify the user making a change in Supabase?
ABy reading session variables or JWT claims
BBy asking the user directly
CBy checking the IP address only
DBy using the database server name
✗ Incorrect
Supabase stores user info in session variables or JWT claims accessible in triggers.
When is a row-level trigger fired?
ABefore or after each row is inserted, updated, or deleted
BOnly once per table update
COnly during database backup
DOnly when a user logs in
✗ Incorrect
Row-level triggers run before or after each row change.
Explain how row-level triggers help maintain audit logs in a Supabase database.
Think about how automatic recording of changes works.
You got /4 concepts.
Describe the key components you would include in an audit log table for tracking row changes.
What details help you understand what changed and who changed it?
You got /5 concepts.
Practice
(1/5)
1. What is the main purpose of a row-level trigger in Supabase for audit logs?
easy
A. To automatically record changes made to individual rows in a table
B. To speed up database queries by caching results
C. To create new tables automatically when data is inserted
D. To delete old data from the database periodically
Solution
Step 1: Understand what row-level triggers do
Row-level triggers activate for each row affected by an insert, update, or delete operation.
Step 2: Connect triggers to audit logs
They are used to record changes to rows, capturing who changed what and when.
Final Answer:
To automatically record changes made to individual rows in a table -> Option A
Quick Check:
Row-level trigger purpose = record row changes [OK]
Hint: Triggers log row changes automatically for audit [OK]
Common Mistakes:
Thinking triggers speed up queries
Confusing triggers with table creation
Assuming triggers delete old data
2. Which of the following is the correct syntax to create a row-level trigger in Supabase that fires AFTER an UPDATE on a table named users?
easy
A. CREATE TRIGGER user_update AFTER INSERT ON users FOR EACH ROW EXECUTE FUNCTION audit_log();
B. CREATE TRIGGER user_update BEFORE UPDATE ON users FOR EACH STATEMENT EXECUTE FUNCTION audit_log();
C. CREATE TRIGGER user_update AFTER UPDATE ON users FOR EACH ROW EXECUTE FUNCTION audit_log();
D. CREATE TRIGGER user_update AFTER UPDATE ON users FOR EACH STATEMENT EXECUTE FUNCTION audit_log();
Solution
Step 1: Identify trigger timing and event
The question asks for AFTER UPDATE trigger on table users.
Step 2: Confirm row-level execution
Row-level triggers use FOR EACH ROW, not FOR EACH STATEMENT.
Final Answer:
CREATE TRIGGER user_update AFTER UPDATE ON users FOR EACH ROW EXECUTE FUNCTION audit_log(); -> Option C
Quick Check:
AFTER UPDATE + FOR EACH ROW = CREATE TRIGGER user_update AFTER UPDATE ON users FOR EACH ROW EXECUTE FUNCTION audit_log(); [OK]
Hint: Use AFTER UPDATE and FOR EACH ROW for row-level update triggers [OK]
Common Mistakes:
Using BEFORE instead of AFTER
Using FOR EACH STATEMENT instead of FOR EACH ROW
Using INSERT event instead of UPDATE
3. Given this trigger function snippet in Supabase SQL:
CREATE OR REPLACE FUNCTION audit_log() RETURNS trigger AS $$
BEGIN
INSERT INTO audit_table(user_id, action, changed_at)
VALUES (NEW.id, TG_OP, NOW());
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
What will happen when a row in the users table is updated?
medium
A. A new row is inserted into audit_table with the user's id, action type, and timestamp
B. The updated row in users is deleted
C. The trigger function will cause a syntax error and fail
D. Nothing happens because OLD is not used
Solution
Step 1: Analyze the trigger function logic
The function inserts a row into audit_table with NEW.id, operation type TG_OP, and current time.
Step 2: Understand trigger behavior on update
On update, NEW holds the new row data, so the insert logs the change.
Final Answer:
A new row is inserted into audit_table with the user's id, action type, and timestamp -> Option A
Quick Check:
Trigger inserts audit record on update = A new row is inserted into audit_table with the user's id, action type, and timestamp [OK]
Hint: Trigger inserts audit row using NEW and TG_OP on update [OK]
Common Mistakes:
Thinking OLD is required for insert
Assuming trigger deletes rows
Confusing syntax causing errors
4. You wrote this trigger function to log deletes:
CREATE OR REPLACE FUNCTION audit_log_delete() RETURNS trigger AS $$
BEGIN
INSERT INTO audit_table(user_id, action, changed_at)
VALUES (NEW.id, TG_OP, NOW());
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
But it fails when deleting rows. What is the error?
medium
A. TG_OP cannot be used in trigger functions
B. RETURN OLD is invalid in DELETE triggers
C. NOW() is not allowed in trigger functions
D. Using NEW.id on DELETE triggers causes an error because NEW is NULL
Solution
Step 1: Understand DELETE trigger context
On DELETE, NEW is NULL because the row is removed; OLD holds the deleted row.
Step 2: Identify the error in the function
The function uses NEW.id which is NULL on DELETE, causing failure.
Final Answer:
Using NEW.id on DELETE triggers causes an error because NEW is NULL -> Option D
Quick Check:
DELETE triggers use OLD, not NEW [OK]
Hint: Use OLD, not NEW, in DELETE triggers to avoid errors [OK]
Common Mistakes:
Using NEW in DELETE triggers
Thinking RETURN OLD is invalid
Believing TG_OP or NOW() cause errors
5. You want to create an audit log that records who updated a row in the orders table, including old and new values. Which approach correctly combines row-level triggers and audit logging in Supabase?
hard
A. Create a trigger function that only logs NEW data and create a BEFORE INSERT trigger on orders
B. Create a trigger function that inserts into audit_orders using both OLD and NEW row data, then create AFTER UPDATE trigger FOR EACH ROW on orders
C. Create a trigger function that deletes old rows from orders and logs the deletion
D. Create a trigger function that logs changes only when rows are inserted, ignoring updates
Solution
Step 1: Identify audit log needs
You want to log who updated rows and capture old and new values for changes.
Step 2: Choose correct trigger timing and data
Use AFTER UPDATE trigger FOR EACH ROW to access OLD and NEW data and insert audit record.
Step 3: Confirm audit table insert logic
The trigger function should insert both OLD and NEW values into audit_orders for full change history.
Final Answer:
Create a trigger function that inserts into audit_orders using both OLD and NEW row data, then create AFTER UPDATE trigger FOR EACH ROW on orders -> Option B
Quick Check:
Use AFTER UPDATE + OLD/NEW + FOR EACH ROW for full audit [OK]
Hint: Use AFTER UPDATE trigger with OLD and NEW for full audit logs [OK]
Common Mistakes:
Logging only NEW data misses old values
Using BEFORE INSERT triggers for updates
Deleting rows instead of logging changes
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.