CASCADE DELETE两个外键约束
问题描述:
我下面举个例子:CASCADE DELETE两个外键约束
Table A
-some_id
Table B
-another_id
Table C
-some_id_fk
-another_id_fk
我想级联上Table C
行如果两个some_id
和another_id
从它们各自的表中删除。
当两个外键被删除时,如何在表C中级联一行?
如果只删除其中一个FK,受影响的行应在引用该外键的列中更改为空值。
答
我建议两个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();
确保连接表具有代理PK列。无论如何,
(a_id, b_id)
不能成为PK,因为这会在两者中都不允许NULL。相反,添加一个UNIQUE
constraint,它允许NULL值。该触发器针对性能进行了优化,并且只在两个FK列中的一个被更新时才启动,并且只有在结果都是
NULL
时才触发。触发器函数很简单:删除行并返回NULL以取消现在无效的级联
UPDATE
。
+0
我希望所有的答案都是这样的质量。丹科! – Matthieu 2016-05-19 10:09:06
只有一个被引用的行被删除时会发生什么?将FK设置为NULL? – 2014-12-19 00:35:15
如果需要,写两个触发器ON DELETE,以便从表C和表B中删除一行。或者最好写两个过程来删除表A和B中的行,并根据需要从表C中删除一行。 – Hovo 2014-12-19 00:36:58
@霍沃我知道触发器是一种选择,但希望有更好的解决方案 – 12preschph 2014-12-19 00:47:09