我正在使用 Postgres 9.3,但遇到了这个问题:我有一个 INPUT 表,我将在其中插入新记录。当我将其插入INPUT时,我想在表A中插入一条新记录:
CREATE FUNCTION A() RETURNS trigger AS $a$
BEGIN
INSERT INTO A(
col1, col2,col3)
values (
NEW.col1,NEW.col2,NEW.col3
);
RETURN NEW;
END;
$a$ LANGUAGE plpgsql;
CREATE TRIGGER a AFTER INSERT ON INPUT
FOR EACH ROW EXECUTE PROCEDURE a();
但之后我还想在表 B 中插入一行,其中表 A 存在外键(B.col1b 必须位于 A.col1 中)。 我写了这个触发器:
CREATE FUNCTION b() RETURNS trigger AS $b$
BEGIN
INSERT INTO B(
col1b, col2b)
select NEW.col1, inp.col5
from INPUT inp
where inp.col1=NEW.col1
;
RETURN NEW;
END;
$b$ LANGUAGE plpgsql;
CREATE TRIGGER b AFTER INSERT ON A
FOR EACH ROW EXECUTE PROCEDURE B();
所以我在INPUT中插入,在A中写入,然后在B中写入,但它不起作用!违反外键错误。 我哪里出错了?
非常感谢!
最佳答案
解决这个问题有两种方法:一种是错误的,一种是正确的。
修复此问题的错误方法是使用 before
触发器。我说错误是因为,简单地说,对其他表的副作用属于 after
触发器,就像您所做的那样。这不仅仅是理论上的:在某些时候预期的副作用包括 psql 报告的错误计数、错误的聚合值,因为表中尚不存在您的行(或其旧值), (如果有更新或删除),怪癖列表还在继续,令人恶心。
修复它的正确方法是使外键可延迟:
http://www.postgresql.org/docs/current/static/sql-createtable.html
FOREIGN KEY ( column_name [, ... ] )
REFERENCES reftable [ ( refcolumn [, ... ] ) ]
[ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
[ ON DELETE action ] [ ON UPDATE action ]
[ DEFERRABLE | NOT DEFERRABLE ]
[ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
您可能希望最初可延迟
。
关于sql - PostgreSQL 触发器在使用外键插入表 A 后插入表 B,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23134553/