简体   繁体   English

PostgreSQL触发器在表A中插入外键后插入表B中

[英]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! 所以我插入I​​NPUT,我用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM