sql - PostgreSQL 触发器在使用外键插入表 A 后插入表 B

标签 sql database postgresql triggers insert

我正在使用 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/

相关文章:

mysql - 使用 double 类型时, double 在 mysql 中无法正常工作

ruby-on-rails - 如何 rake 数据库 :migrate on a Heroku staging pipeline?

SQL 查询从日志表计算访问持续时间

MYSQL SELECT 行的总和超过 200

mysql 多重内连接复杂度

sql - 如何连接两个表,同时删除一个表的一列中的重复条目

postgresql - Sequelize.js - 如何在没有原始 SQL 的情况下创建重要的关联?

c# - 是否可以(以编程方式)证明两个 LINQ 查询相等?

sql - SQL Server如何从另一个数据库中选择一个表的数据?

php - Mysql 数据库 - 使用下拉框和搜索字段对数据输出进行排序