[英]PostgreSQL Trigger Insert in table B after insert in table A with a foreign key
I'm using Postgres 9.3 and I have this problem: I have a table INPUT where I'll insert new record. 我正在使用Postgres 9.3,我遇到了这个问题:我有一个表INPUT,我将插入新记录。 I want insert a new record in table A when I insert it in 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();
But AFTER I want to insert a row in table B also, where there is a foreign key with table A (B.col1b must be in A.col1). 但是我想在表B中插入一行,其中有一个表A的外键(B.col1b必须在A.col1中)。 I wrote this trigger: 我写了这个触发器:
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();
So I insert in INPUT, I write in A and after I write in B, but it doesn't work! 所以我插入INPUT,我用A写,然后用B写,但它不起作用! Error by foreign key violated. 外键违反时出错。 Where I make a mistake? 哪里弄错了?
Thank you very much! 非常感谢你!
Two ways to fix it: one wrong, and one correct. 解决它的两种方法:一种是错误的,一种是正确的。
The wrong way to fix it is to use a before
trigger. 修复它的错误方法是使用before
触发器。 I say wrong because, simply put, side effects on other tables belong in an after
trigger like you did. 我说错了,因为简单地说,对其他表的副作用属于after
触发器,就像你做的那样。 This not just in theory: side effects to expect at some point or another include incorrect counts reported by psql
, wrong aggregate values because your row doesn't exist in a table yet (or its old value does, in case of updates or deletes), the list of quirks goes on and on ad nausea. 这不仅仅是理论上的:在某些时候预期的副作用包括psql
报告的错误计数,错误的聚合值因为你的行还没有存在于表中(或者在更新或删除的情况下它的旧值) ,怪异的列表继续和恶心。
The correct way is to fix it is to make your foreign key deferrable: 正确的方法是修复它是为了使你的外键可以推迟:
http://www.postgresql.org/docs/current/static/sql-createtable.html 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 ]
You probably want deferrable initially deferred
. 您可能希望deferrable initially deferred
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.