我正在为插入表A时触发的触发器设置一个函数,我将首先在表B中创建一个条目,然后在表C中创建一些其他条目,其中有一个与表B相关的外键。但是我收到一个错误,因为它尝试在 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;
我试图将函数分离到两个不同的触发器中,使用字母顺序对执行进行排序,但没有成功,也许是因为它们之前都运行过......
知道吗?
谢谢
将 tableC 中的外键声明为 DEFERRABLE INITIALLY DEFERRED
。
从文档中:
可递延 不可递延
这控制是否可以延迟约束。不可延迟的约束将在每次后立即检查 命令。可以推迟检查可延迟的约束 直到事务结束(使用 SET 约束命令(。 不可延迟是默认值。目前,只有唯一,主键, 排除和引用(外键(约束接受此子句。 NOT NULL 和 CHECK 约束不可延迟。
顺便说一句,函数体中的第一个RETURN NEW;
毫无意义。
首先,不可能在同一个函数流中有两个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();
更多信息在这里