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

syntax Error in PostgreSQL when I try to create Trigger

我想在 PostgreSQL 中创建触发器。

逻辑很简单

我需要触发器,如果​​ published_at 已更新且 written_at 为空,请将 published_at 设置为 written_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 行:声明 old_id 整数;

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

  • 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 
    <b>BEFORE</b> UPDATE OF published_at ON review
    WHEN (OLD.published_at IS DISTINCT FROM NEW.published_at)
    FOR EACH ROW
    EXECUTE PROCEDURE setWrittenAt();

这是基于 a_horse_with_no_names ,因为它会抛出错误。

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

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

If neither is specified, FOR EACH STATEMENT is the default.

Statement-level triggers can also have WHEN conditions, although the feature is not so useful for them since the condition cannot refer to any values in the table.

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();

我还不能发表评论,这就是我将此作为答案发布的原因。