【问题标题】:relation "old" does not exist关系“旧”不存在
【发布时间】:2017-04-22 04:41:13
【问题描述】:

当我尝试执行这个脚本时,我得到一个错误: 错误:关系“旧”不存在。 脚本:

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

【问题讨论】:

  • 我不明白您为什么要删除删除触发器已删除的行(然后再次重新插入该行)。这似乎很奇怪。

标签: postgresql triggers


【解决方案1】:

对于第一个INSERT,使用类似

INSERT INTO organization_history VALUES (OLD.*);

DELETE 和第二个 INSERT 设计不当 - 一方面,这会在 organization 表中造成大量不必要的流失。

最好使用BEFORE 触发器,将NEW.version 加1 并返回NEW。这将导致在记录写入表之前调整值。

【讨论】:

    【解决方案2】:

    您误解了OLDNEW 是什么:它们不是表格,而是已插入或修改的

    但是,您不需要删除和插入所有内容。只需在 BEFORE 触发器中增加版本即可。

    然后您可以将触发器简化为:

    create or replace function pmigratedatatohistory()
    returns trigger as $$
    BEGIN
      insert into organization_history values (old.*);
      new.version := new.version + 1; -- increment the version
      return new;
    END;
    $$ 
    LANGUAGE plpgsql;
    

    为此,您需要一个BEFORE触发器:

    create trigger trmigratedatatohistory BEFORE update or delete ON organization
        for each row execute procedure pmigratedatatohistory();

    删除行的过程对我来说没有意义。当前代码执行以下操作:

    1. 一个delete from organization被执行,行被删除
    2. 触发器复制该行
    3. 触发器尝试再次删除该行(什么也不做,因为它是一个after 触发器,所以该行已经从表中消失了)
    4. 装配工重新插入本应使用更高版本号删除的行 - 实质上是完全恢复删除。

    通过在前触发器中简单地增加版本可以实现相同的行为。如果您想完全防止删除,只需在 before 触发器中返回 null

    create or replace function pmigratedatatohistory()
    returns trigger as $$
    BEGIN
      insert into organization_history values (old.*);
      new.version := new.version + 1; -- increment the version
      if TG_OP = 'DELETE' then 
        return null; -- "cancel" the delete 
      else
        return new;
      endif;
    END;
    $$ 
    LANGUAGE plpgsql;
    

    【讨论】:

      猜你喜欢
      • 2013-05-21
      • 2017-04-20
      • 2022-01-22
      • 2021-03-30
      • 2017-10-19
      • 2017-07-05
      • 2023-04-03
      • 2021-06-28
      • 1970-01-01
      相关资源
      最近更新 更多