尝试创建触发器时PostgreSQL中的语法错误

时间:2020-05-20 07:34:45

标签: sql postgresql plpgsql database-trigger

我想在PostgreSQL中创建触发器。

逻辑很简单。

我需要触发器,如果​​published_at已更新,并且writed_at为null,请将published_at设置为writerd_at。

我写了这个,但是失败了。有人有主意吗?

CREATE function setWrittenAt() RETURNS trigger;
AS 
DECLARE old_id INTEGER;
BEGIN ;
old_id = OLD.id
  IF NEW.published_at IS NOT and NEW.written_at IS null
    THEN
    UPDATE review SET NEW.written_at = NEW.published_at where id = old_id;
 END IF ;
RETURN NEW;
END;
LANGUAGE plpgsql;


CREATE TRIGGER update_written_at 
    AFTER UPDATE OF published_at ON review
    WHEN (OLD.published_at IS DISTINCT FROM NEW.published_at)
    EXECUTE PROCEDURE setWrittenAt();

错误:

语法错误:7错误:“ DECLARE”或附近的语法错误 第3行:DECLARE old_id INTEGER;

2 个答案:

答案 0 :(得分:2)

您的代码中存在多个错误:

  • IS NOT不是您需要的有效表达式IS NOT NULL
  • BEGINreturns子句之后,不得有;
  • 您忘记了将函数体作为字符串括起来(如果使用dollar quoting,则更容易编写
  • 如果您将其设为UPDATE触发器,则也不需要不必要的before
CREATE function setwrittenat() 
  RETURNS trigger
AS 
$$
BEGIN
  IF NEW.published_at IS NOT NULL and NEW.written_at IS null THEN
    NEW.written_at := = NEW.published_at; --<< simply assign the value
  END IF;
  RETURN NEW;
END;
$$
LANGUAGE plpgsql;

然后使用BEFORE触发器:

CREATE TRIGGER update_written_at 
    BEFORE UPDATE OF published_at ON review
    WHEN (OLD.published_at IS DISTINCT FROM NEW.published_at)
    FOR EACH ROW
    EXECUTE PROCEDURE setWrittenAt();

答案 1 :(得分:1)

这基于a_horse_with_no_name的{​​{3}},因为它将引发错误。

ERROR: statement trigger's WHEN condition cannot reference column values

您需要添加FOR EACH ROW,否则条件触发器将不起作用。

如果均未指定,则FOR EACH STATEMENT是默认值。

语句级触发器也可以具有WHEN条件,尽管该功能对它们没有太大用处,因为条件不能引用表中的任何值。

answer

CREATE TRIGGER update_written_at
    BEFORE UPDATE OF published_at ON review
    FOR EACH ROW
    WHEN (OLD.published_at IS DISTINCT FROM NEW.published_at)
    EXECUTE PROCEDURE setWrittenAt();

我无法发表评论,这就是为什么我将其发布为答案。