postgresql 关系“旧”不存在

uajslkp6  于 2023-06-29  发布在  PostgreSQL
关注(0)|答案(3)|浏览(167)

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

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

wooyq4lh1#

对于第一个INSERT,请使用类似

INSERT INTO organization_history VALUES (OLD.*);

DELETE和第二个INSERT考虑不周-首先,这将导致organization表中大量不必要的流失。
最好使用BEFORE触发器,NEW.version加1,返回NEW。这将导致在记录写入表之前 * 调整值。

ws51t4hk

ws51t4hk2#

你误解了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并删除该行
1.触发器将复制该行
1.触发器尝试删除该行再次(并且什么也不做,因为它是after触发器,所以该行已经从表中删除)
1.装配人员重新插入本应使用更高版本号删除的行-实际上完全恢复了删除操作。
通过简单地递增before触发器中的版本可以实现相同的行为。如果你想完全阻止删除,只需在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;
7nbnzgx9

7nbnzgx93#

@Laurenz Albe是对的,关于使用“DELETE”,你必须使用“BEFORE”而不是“AFTER”,下面是我的例子(使用postgresql):

create table if not exists v08_orders (
order_id serial primary key,
order_date DATE,
customer_name varchar(50));


create table if not exists v08_order_logs(
log_id serial primary key,
order_id INT,
log_date TIMESTAMP default CURRENT_TIMESTAMP,
log_text TEXT,
FOREIGN KEY (order_id) REFERENCES v08_orders (order_id) on delete set null);

创建或替换函数func_delete_order()返回触发器作为$开始插入到v08_order_logs(order_id,log_text)值(OLD.order_id,'an order is deleted ar:”||CURRENT_TIMESTAMP); return OLD;$$ language plpgsql;

CREATE or replace TRIGGER order_delete_trigger
before DELETE ON v08_orders
FOR EACH ROW
execute function func_delete_order();

因此,每次从订单中删除项目时,在实际删除之前,将触发在order_logs表中添加一个日志的操作

相关问题