我使用的是Postgres 9.3,我遇到了这个问题:我有一个表INPUT,我将插入新记录。我想在INPUT中插入一条新记录:
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写,但它不起作用!外键违反时出错。 我犯错的地方?
非常感谢!
答案 0 :(得分:3)
两种解决方法:一种是错误的,一种是正确的。
修复它的错误方法是使用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 ]
您可能想要deferrable initially deferred
。