Fire trigger on update of columnA or ColumnB or ColumnC

后端 未结 3 795
旧时难觅i
旧时难觅i 2020-12-28 16:38

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

相关标签:
3条回答
  • 2020-12-28 17:05

    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';
    
    0 讨论(0)
  • 2020-12-28 17:12

    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 OFcolumn_name syntax) will fire when any of its columns are listed as targets in the UPDATE command's SET 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 by BEFORE UPDATE triggers 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)
    ...
    
    0 讨论(0)
  • 2020-12-28 17:19

    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();
    
    0 讨论(0)
提交回复
热议问题