Fire trigger on update of columnA or ColumnB or ColumnC
This is a misunderstanding. The
WHEN clause of the trigger definition expects a
boolean expression and you can use
OR operators in it. This should just work (given that all columns actually exist in the table
account_details). I am using similar triggers myself:
CREATE TRIGGER trigger_update_account_details AFTER UPDATE ON account_details FOR EACH ROW WHEN (OLD.email IS DISTINCT FROM NEW.email OR OLD.username IS DISTINCT FROM NEW.username OR OLD.password IS DISTINCT FROM NEW.password) EXECUTE PROCEDURE notify_insert_account_details();
Evaluating the expression has a tiny cost, but this is probably more reliable than the alternative:
CREATE TRIGGER ... AFTER UPDATE OF email, username, password ...
Because, per documentation:
A column-specific trigger (one defined using the
column_namesyntax) will fire when any of its columns are listed as targets in the
SETlist. It is possible for a column's value to change even when the trigger is not fired, because changes made to the row's contents by
BEFORE UPDATEtriggers are not considered. Conversely, a command such as
UPDATE ... SET x = x ...will fire a trigger on column x, even though the column's value did not change.
ROW type syntax is shorter to check on many columns (doing the same):
CREATE TRIGGER trigger_update_account_details AFTER UPDATE ON account_details FOR EACH ROW WHEN ((OLD.email, OLD.username, OLD.password, ...) IS DISTINCT FROM (NEW.email, NEW.username, NEW.password, ...)) EXECUTE PROCEDURE notify_insert_account_details();
Or, to check for every visible user column in the row:
... WHEN (OLD IS DISTINCT FROM NEW) ...
The above solutions were not working for me properly. So after reading through documentation again. I found few things to take note of. BEFORE UPDATE ON - AFTER UPDATE ON triggers are executed differently. Since my procedure was returning the NEW record with updated value. It was not working in AFTER trigger and in BEFORE trigger, the OR statements inside WHEN clause needed to be enclosed by braces.
CREATE TRIGGER check_update BEFORE UPDATE ON some_table FOR EACH ROW WHEN ((OLD.colum_name_1 IS DISTINCT FROM NEW.colum_name_1) OR (OLD.colum_name_2 IS DISTINCT FROM NEW.colum_name_2)) EXECUTE PROCEDURE update_updated_at_column();
And the procedure
CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = now(); RETURN NEW; END; $$ language 'plpgsql';
I don't think you need the
WHEN clause. You can specify the columns in question in the UPDATE clause:
CREATE TRIGGER trigger_update_account_details AFTER UPDATE OF email, username, password ON account_details FOR EACH ROW EXECUTE PROCEDURE notify_insert_account_details();