Postgres SQL 触发器在 TableB 上插入或更新后使用新值更新 TableA.column

Posted

技术标签:

【中文标题】Postgres SQL 触发器在 TableB 上插入或更新后使用新值更新 TableA.column【英文标题】:Postgres SQL trigger to update TableA.column with NEW value AFTER INSERT OR UPDATE on TableB 【发布时间】:2018-09-24 22:23:39 【问题描述】:

我有一个非常简单的触发器,它会在 table_b 更新时更新 table_a 中的列:

create or replace function trigger_update_status()
    returns trigger as 
    $body$
    begin

-- UPDATE TABLE A   
update table_a
    set a_status = new.b_status,
        date_updated = now()
    from table_b
        where table_a.serial_number = table_b.serial_number; 

    return new;

end;
$body$
language plpgsql;

create trigger "currentStatus" after update or insert on table_b
for each row 
execute procedure trigger_update_status();

但是,我收到没有RETURN 值的错误:

ERROR: control reached end of trigger procedure without RETURN

我对@9​​87654327@ 在这里是否合适感到困惑,因为我一直在阅读相互矛盾的信息。 一方面,这里的答案 (Postgres trigger after insert accessing NEW) 清楚地表明:“始终忽略 AFTER 触发的行级触发器或 BEFORE 或 AFTER 触发的语句级触发器的返回值;它可能是最好是 null。但是,这些类型的触发器中的任何一个仍可能通过引发错误来中止整个操作。"

另一方面,我这里的触发器基本上与这里的触发器 (https://dba.stackexchange.com/questions/182678/postgresql-trigger-to-update-a-column-in-a-table-when-another-table-gets-inserte) 匹配,它同时调用了 NEWAFTER。所以我不确定为什么我的不工作。非常感谢任何帮助!

【问题讨论】:

为我工作:dbfiddle.uk/… 【参考方案1】:

对于任何有相同问题的人的未来答案:它是第二个(名称类似,这就是为什么我直到很久以后才抓住它)触发器,它在导致问题的这个触发器之后被调用。第二个触发器不能RETURN NEW,因为在这种情况下,没有新值。我通过在第二个触发器中添加 IF/ELSE 语句来解决此问题:

IF NEW.current_location <> OLD.current_location 
    THEN
    INSERT INTO table_x(serial_number, foo, bar)
        VALUES(OLD.serial_number, OLD.foo, old.bar);
    return new;

-- ADDED THIS LINE: 
    else return null;
END IF;

感谢@sticky bit 吸取的教训 - 如果触发器在一个孤立的 dbfiddle 中工作,那么它是导致问题的其他原因。

【讨论】:

以上是关于Postgres SQL 触发器在 TableB 上插入或更新后使用新值更新 TableA.column的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server实时同步更新远程数据库遇到的问题

如何合并表上的行并更新 postgres 上的联结表

使用触发器将 postgres SQL 插入语句拆分为 2 个表

REstore只触发postgres

创建或替换触发器 postgres

SQL 查询 - 在小于或等于日期时加入