当我尝试执行这个脚本时,我得到一个错误:错误:关系“旧”不存在。脚本:
update organization
set row_status = 30;
我发现了一些这样的问题,但他们没有帮助我。我的触发器:
Create OR REPLACE function PMigrateDataToHistory()
returns trigger as $PMigrateDataToHistory$
begin
insert into organization_history
select
*
from
OLD;
delete
from
organization as org USING
OLD as o
where
o.id = org.id and
o.version = org.version;
insert into organization
select
n.id,
n.created_at,
n.updated_at,
n.row_status,
n.version + 1,
n.resource
from
NEW as n;
end;
$PMigrateDataToHistory$ LANGUAGE plpgsql;
CREATE TRIGGER TRMigrateDataToHistory AFTER update or delete ON organization
FOR EACH ROW EXECUTE PROCEDURE PMigrateDataToHistory();
3条答案
按热度按时间wooyq4lh1#
对于第一个
INSERT
,请使用类似DELETE
和第二个INSERT
考虑不周-首先,这将导致organization
表中大量不必要的流失。最好使用
BEFORE
触发器,NEW.version
加1,返回NEW
。这将导致在记录写入表之前 * 调整值。ws51t4hk2#
你误解了
OLD
和NEW
是什么:这些不是表,是插入或修改的行。但是,您不需要删除和插入所有内容。只需在BEFORE触发器中递增版本即可。
然后,您可以将触发器简化为:
你需要一个BEFORE触发器:
删除一行的过程对我来说没有意义。当前代码执行以下操作:
1.执行
delete from organization
并删除该行1.触发器将复制该行
1.触发器尝试删除该行再次(并且什么也不做,因为它是
after
触发器,所以该行已经从表中删除)1.装配人员重新插入本应使用更高版本号删除的行-实际上完全恢复了删除操作。
通过简单地递增before触发器中的版本可以实现相同的行为。如果你想完全阻止删除,只需在before触发器中返回
null
:7nbnzgx93#
@Laurenz Albe是对的,关于使用“DELETE”,你必须使用“BEFORE”而不是“AFTER”,下面是我的例子(使用postgresql):
创建或替换函数func_delete_order()返回触发器作为$开始插入到v08_order_logs(order_id,log_text)值(OLD.order_id,'an order is deleted ar:”||CURRENT_TIMESTAMP); return OLD;$$ language plpgsql;
因此,每次从订单中删除项目时,在实际删除之前,将触发在order_logs表中添加一个日志的操作