I am creating a sports database and am trying to add a trigger to my DDL. The aim of the trigger is to insert values into a table (commitment) whenever another table (player) has a college commitment (col_commit) change from FALSE to TRUE. Whenever this happens I want to insert the player’s id and the date of the update. This is what I have so far:
CREATE OR REPLACE FUNCTION commitment_log()
RETURNS TRIGGER
LANGUAGE plpgsql
AS
$$
BEGIN
IF OLD.col_commit = TRUE THEN
INSERT INTO commitment(player_id, committed_date)
VALUES (OLD.player_id, now());
END IF;
RETURN NEW;
END;
$$;
CREATE TRIGGER commitment_trigger
BEFORE UPDATE
ON player
FOR EACH ROW
EXECUTE PROCEDURE commitment_log();
As of now, when I update a player’s commitment in the player table to TRUE, nothing is updated in the commitment table.
2
Answers
You’re checking
old.col_commit=TRUE
instead ofnew.col_commit=TRUE and old.col_commit=FALSE
that you described.Basic demo
I didn’t initially stress this, but specifying your condition in trigger
WHEN
section as I suggest above is just better for performance. If you do it at the beginning of trigger body, it’ll always fire on update, adding overhead, even if it’s not needed.If you do it in
WHEN
, it’ll do the check and abort without firing and incurring costs related to that. Note shorter execution time and no trigger calls compared to the earlier plan:See this demo.
OLD refers to the data that where before the update and NEW to the updated values.
As you only check the OLD.col_commit data, that is FALSE, you never will get a log entry.
so simply change the trigger to check for NEW.col_commit
Belayer is right, this should be an
AFTER UPDATE TRIGGER
vecause, it will only be run when the update was commited, aBEFORE UPDATE TRIGGER
will run before the commit and could change the datasee sample fiddle
Of course, if you want only to capture the changes from FALSE to TRUE, you need also to check the OLD value