Postgres SQL触发器使用TableB上的INSERT或UPDATE之后的新值更新TableA.column

时间:2018-09-24 22:23:40

标签: sql postgresql triggers database-trigger

我有一个非常简单的触发器,只要更新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

由于我一直在阅读有冲突的信息,因此我对NEW是否合适感到困惑。 一方面,这里的答案(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。所以我不确定为什么我的不工作。任何帮助都将不胜感激!

1 个答案:

答案 0 :(得分:0)

针对任何存在相同问题的人的未来答案:这是第二个触发(类似的原因,这就是为什么我直到很晚才抓到它)的触发原因,而这个触发原因是第二个触发。第二个触发器无法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位,教训中学到了-如果触发器在隔离的dbfiddle中工作,则是导致问题的其他原因。