sql—尝试创建触发器时postgresql中的语法错误

kt06eoxx  于 2021-06-29  发布在  Java
关注(0)|答案(2)|浏览(528)

我想在postgresql中创建触发器。
逻辑很简单。
我需要触发器,如果published\u at updated和writed\u at为空,则将published\u at设置为writed\u 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:声明旧的\u id整数;

5jdjgkvh

5jdjgkvh1#

这是基于 a_horse_with_no_name 因为它会抛出一个错误。 ERROR: statement trigger's WHEN condition cannot reference column values 你需要加上 FOR EACH ROW ,否则条件触发器将不起作用。
如果两者都未指定,则默认为for each语句。
语句级触发器也可以具有when条件,不过由于条件不能引用表中的任何值,因此该特性对它们不是很有用。
看到这里了吗

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

我还不能发表评论,这就是为什么我把这个作为一个答案。

laawzig2

laawzig22#

代码中有多个错误: IS NOT 不是您需要的有效表达式 IS NOT NULL .
之后 BEGIN 以及 returns 条款必须没有 ; 您忘了将函数体作为字符串括起来(如果使用美元引号,那么编写起来更容易)
你也不需要一个不必要的(额外的) 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();

相关问题