CASCADE DELETE有两个外键约束

时间:2014-12-19 00:31:33

标签: sql database postgresql database-design cascade

我有以下示例:

Table A
   -some_id

Table B
   -another_id

Table C
   -some_id_fk
   -another_id_fk

如果Table Csome_id从各自的表中删除,我想在another_id上级联一行。

当删除两个外键时,如何在表C中自行级联?

如果只删除了其中一个FK,受影响的行应该在引用该外键的列中更改为空值。

1 个答案:

答案 0 :(得分:7)

我建议使用两个foreign key constraints with ON DELETE SET NULL和一个负责其余的触发器

表:

CREATE TABLE a (a_id serial PRIMARY KEY, a text NOT NULL);
CREATE TABLE b (b_id serial PRIMARY KEY, b text NOT NULL);

CREATE TABLE ab (
  ab_id serial PRIMARY KEY
, a_id int REFERENCES a ON DELETE SET NULL
, b_id int REFERENCES b ON DELETE SET NULL
, UNIQUE (a_id, b_id)
);

触发:

CREATE OR REPLACE FUNCTION trg_ab_upbef_nulldel()
  RETURNS trigger AS
$func$
BEGIN
DELETE FROM ab WHERE ab_id = NEW.ab_id;
RETURN NULL;
END
$func$ LANGUAGE plpgsql;

CREATE TRIGGER upbef_nulldel
BEFORE UPDATE OF a_id, b_id ON ab
FOR EACH ROW
WHEN (NEW.a_id IS NULL AND
      NEW.b_id IS NULL)
EXECUTE PROCEDURE trg_ab_upbef_nulldel();

SQL Fiddle.

  • 确保连接表具有代理PK列。 (a_id, b_id)无论如何都不能成为PK,因为这两者都不允许使用NULL。改为添加UNIQUE constraint,允许NULL值。

  • 触发器针对性能进行了优化,只有在更新两个FK列中的一个时才会启动,并且只有当这两个FK列都导致NULL时才会启动。

  • 触发器功能很简单:删除行并返回NULL以取消现在无效的级联UPDATE