I have the code to fire a trigger only on an update of a single specific column. The trigger is used to fire a function that will raise a postgres "notify" event, which I am listening for and will need to test and validate the newly input details. There are many values on the account_details table which could be change which do not require an account validate, so a trigger on AFTER UPDATE only (without a when) is no good.
CREATE TRIGGER trigger_update_account_details AFTER UPDATE ON account_details FOR EACH ROW WHEN (OLD.email IS DISTINCT FROM NEW.email) EXECUTE PROCEDURE notify_insert_account_details();
But I want to fire the trigger if one of many columns change, something like
WHEN (OLD.email IS DISTINCT FROM NEW.email OR OLD.username IS DISTINCT FROM NEW.username OR OLD.password IS DISTINCT FROM NEW.password)
But OR is not a valid keyword for a trigger. Trying to search for the keyword to use instead of OR doesn't seem to bring up anything due the nature of the word OR :-(
Using a SQL Server trigger to check if a column is updated, there are two ways this can be done; one is to use the function update(<col name>) and the other is to use columns_updated().
A trigger fired by an INSERT statement has meaningful access to new column values only. Because the row is being created by the INSERT operation, the old values are null. A trigger fired by an UPDATE statement has access to both old and new column values for both BEFORE and AFTER row triggers.
In SQL Server, you can create DML triggers that execute code only when a specific column is updated. The trigger still fires, but you can test whether or not a specific column was updated, and then run code only if that column was updated. You can do this by using the UPDATE() function inside your trigger.
CREATE TRIGGER [SCHEMA_NAME]. [YOUR_TRIGGER_NAME] ON YOUR_TABLE_NAME AFTER UDATE AS BEGIN {SQL STATEMENTS} END; UPDATE TABLE_NAME SET COLUMN_NAME= NEW_VALUE WHERE [CONDITIONS]; Let's see the syntax explanation: SCHEMA_NAME: it is the name of the schema in which we will create a new trigger in the database.
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
UPDATE OF
column_name
syntax) will fire when any of its columns are listed as targets in theUPDATE
command'sSET
list. 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 byBEFORE UPDATE
triggers are not considered. Conversely, a command such asUPDATE ... 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) ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With