【问题标题】:PostgreSQL trigger after update only on a updated row仅在更新的行上更新后的 PostgreSQL 触发器
【发布时间】:2017-12-11 17:53:15
【问题描述】:

我有一张小桌子来放新闻。我想创建一个触发器,在行中设置更新日期和更新时间(仅适用于已更新的行)

我尝试制作以下内容:

CREATE FUNCTION add_update_dates()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
  IF (OLD.news_name IS DISTINCT FROM NEW.news_name OR
  OLD.news_description IS DISTINCT FROM NEW.news_description OR
  OLD.news_text IS DISTINCT FROM NEW.news_text) THEN
  UPDATE news SET news_update_date = current_date, news_update_time = current_time;
END IF;
RETURN new;
END
$$;

CREATE TRIGGER update_news_dates
AFTER UPDATE ON news
FOR EACH ROW
EXECUTE PROCEDURE add_update_dates();

但是当我只想要更新的行时,触发器会更新我表中的每一行(即使是那些未更新的行)。我做错了什么?

【问题讨论】:

  • Postgresql 是否允许在触发器内部的同一张表上更新表语句?我的意思是,在 oracle 中,我们会收到一个 mutating table 错误。
  • @KaushikNayak:我认为在AFTER UPDATE 触发器中是允许的,但在BEFORE UPDATE 触发器中是不允许的

标签: sql postgresql triggers plpgsql


【解决方案1】:

您的update 语句正在更新表中的所有行!它没有where 子句。

只使用赋值:

CREATE FUNCTION add_update_dates()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
  IF (OLD.news_name IS DISTINCT FROM NEW.news_name OR
      OLD.news_description IS DISTINCT FROM NEW.news_description OR
      OLD.news_text IS DISTINCT FROM NEW.news_text
     ) THEN
    NEW.news_update_date := current_date;
    NEW.news_update_time := current_time;
  END IF;
  RETURN new;
END;
$$;

顺便说一句,将日期/时间存储在单独的列中对我来说毫无意义。

【讨论】:

  • 您还需要将触发器定义更改为BEFORE UPDATE
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多