我在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之前运行...
有什么想法吗?
由于
答案 0 :(得分:2)
将tableC中的外键声明为DEFERRABLE INITIALLY DEFERRED
。
可推迟不可推迟
这可以控制是否可以延迟约束。每次都会立即检查不可延迟的约束 命令。可以推迟检查可延迟的约束 直到事务结束(使用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