Support wants a record of every email change. Each program that changes an email could write that record, but one of them will forget. A makes the database write it on every change.
Two parts
UPDATE customers SET email = …any program
fires
log_emailthe trigger
runs
INSERT INTO email_log …the trigger function
1. The trigger function. It returns the type trigger. Inside it, OLD is the row before the change and NEW is the row after it:
sql
CREATE TABLE email_log (customer_id integer, old_email text, new_email text);
CREATE FUNCTION log_email_change()
RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
INSERT INTO email_log VALUES (OLD.id, OLD.email, NEW.email);
RETURN NEW;
END;
$$;2. The trigger. It connects the function to a table and an event:
sql
CREATE TRIGGER log_email
AFTER UPDATE OF email ON customers
FOR EACH ROW
EXECUTE FUNCTION log_email_change();CREATE TRIGGER log_emailnameAFTER UPDATE OF emailwhen, and on which changeON customerstableFOR EACH ROWonce per changed rowEXECUTE FUNCTION log_email_change()what to run
AFTER UPDATEfires after each update.OF emaillimits it to updates that setemail. WithoutOF …, every UPDATE fires it.INSERTandDELETEwork the same. An INSERT has onlyNEW; a DELETE has onlyOLD.BEFOREtriggers run first and can changeNEWbefore PostgreSQL stores it.RETURN NEW;ends the function. An AFTER trigger ignores the value, but the function must return one.
Now change an email and read the log:
sql
UPDATE customers SET email = 'ava@monster.example' WHERE id = 1;
SELECT * FROM email_log;email_log
| customer_id | old_email | new_email |
|---|---|---|
| 1 | ava.chen@example.com | ava@monster.example |