Postgresql 在更新时执行过程(值已更改)

Postgresql execute procedure on update (value changed)

我有以下 trigger 调用 update_recipe_timestamp_proc function 更新 modified_on 列。 如果相同的值得到 inserted/updated,尽管没有提供新值,trigger 仍然会被触发!

触发器

CREATE TRIGGER update_recipes_timestamp_r 
BEFORE UPDATE OF "identifier", "name", "description"
ON recipes 
FOR EACH ROW EXECUTE PROCEDURE update_recipe_timestamp_proc();

函数

CREATE OR REPLACE FUNCTION update_recipe_timestamp_proc()
RETURNS TRIGGER AS $$
BEGIN
    NEW."modified_on" = now();
    RETURN NEW;   
END;
$$ language 'plpgsql';

我是否必须根据结果在我的函数和 return NULLNEW 中编写逻辑,或者是有简单的解决办法吗?

无论新值与旧值是否不同,都会执行UPDATE,同样适用于触发器。

三种可能的解决方案:

  1. 根据 Sevanteri 的评论建议,使用

    CREATE TRIGGER update_recipes_timestamp_r 
    BEFORE UPDATE OF "identifier", "name", "description"
    ON recipes FOR EACH ROW
    WHEN (OLD IS DISTINCT FROM NEW)
    EXECUTE PROCEDURE update_recipe_timestamp_proc();
    
  2. 这样写触发程序:

    IF (OLD IS DISTINCT FROM NEW) THEN
       NEW."modified_on" = now();
       RETURN NEW;   
    END IF;
    
  3. 使 UPDATE 成为条件:

    UPDATE recipes
       SET "identifier" = val1, "name" = val2, "description" = val3
    WHERE ...
      AND "identifier" <> val1 OR "name" <> val2 OR "description" <> val3;
    

使用 WHEN 的解决方案仅在特定列更改时更新 modified_on 列。

CREATE TRIGGER update_recipes_timestamp_r BEFORE 
UPDATE ON recipes FOR EACH ROW
WHEN (
OLD."name" <> NEW."name" OR 
OLD."description" <> NEW."description" OR
OLD."identifier" <> NEW."identifier")
EXECUTE PROCEDURE update_recipe_timestamp_proc();