测序结果导致PostgreSQL 9.5功能

时间:2017-05-22 13:47:29

标签: postgresql triggers

我在tableA中插入时触发了触发器的函数,我首先在tableB中创建一个条目,然后在tableC中创建一些其他条目,其中有一个与tableB相关的外键。但是我得到一个错误,因为它尝试在tableC中插入一个值,只要该函数没有完成运行,就会在tableB中不存在这个值。

有没有一种方法在函数内部,在我的函数内部放置某种返回但是不会退出函数然后执行其余部分?看起来像这样的东西:

CREATE OR REPLACE FUNCTION trigger1() RETURNS trigger AS
$BODY$
begin
insert into tableB values (new.value);
RETURN NEW;
insert into tableC (id, fkey) values (new.something, new.value);
RETURN NEW;
end;
$BODY$
LANGUAGE plpgsql;

我尝试将函数分成两个不同的触发器,使用字母顺序来命令执行,但没有成功,可能是因为它们都是在BEFORE之前运行...

有什么想法吗?

由于

2 个答案:

答案 0 :(得分:2)

将tableC中的外键声明为DEFERRABLE INITIALLY DEFERRED

来自the documentation:

  

可推迟不可推迟

     

这可以控制是否可以延迟约束。每次都会立即检查不可延迟的约束   命令。可以推迟检查可延迟的约束   直到事务结束(使用SET CONSTRAINTS命令)。   NOT DEFERRABLE是默认值。目前,只有UNIQUE,PRIMARY KEY,   EXCLUDE和REFERENCES(外键)约束接受此子句。   NOT NULL和CHECK约束不可延迟。

顺便说一下。函数体中的第一个RETURN NEW;没有任何意义。

答案 1 :(得分:2)

首先,在函数的同一流中不可能有两个RETURN语句。

关于您的问题,有很多方法可以实现这一目标。其中一个是使用DEFERRABLE TRIGGER(在事务结束时评估的特殊类型的触发器)。类似的东西:

--Trigger function
CREATE OR REPLACE FUNCTION trigger1() RETURNS trigger AS
$BODY$
BEGIN
    INSERT INTO "tableB" VALUES (new.value);
    INSERT INTO "tableC" (id, fkey) VALUES (new.something, new.value);
    RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;

--Trigger raised at end of transaction. Take a look on 'CONSTRAINT' and 'INITIALLY DEFERRED' clauses.
CREATE CONSTRAINT TRIGGER deferred_trigger_1
  AFTER INSERT OR UPDATE
  ON "tableA"
  INITIALLY DEFERRED  
  FOR EACH ROW
  EXECUTE PROCEDURE trigger1();

更多信息here