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

时间:2014-04-17 13:31:54

标签: sql database postgresql triggers insert

我使用的是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();

所以我插入I​​NPUT,我用A写,然后用B写,但它不起作用!外键违反时出错。 我犯错的地方?

非常感谢!

1 个答案:

答案 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