2014-12-19 77 views
6

我下面舉個例子:CASCADE DELETE兩個外鍵約束

Table A 
    -some_id 

Table B 
    -another_id 

Table C 
    -some_id_fk 
    -another_id_fk 

我想級聯上Table C行如果兩個some_idanother_id從它們各自的表中刪除。

當兩個外鍵被刪除時,如何在表C中級聯一行?

如果只刪除其中一個FK,受影響的行應在引用該外鍵的列中更改爲空值。

+2

只有一個被引用的行被刪除時會發生什麼?將FK設置爲​​NULL? – 2014-12-19 00:35:15

+2

如果需要,寫兩個觸發器ON DELETE,以便從表C和表B中刪除一行。或者最好寫兩個過程來刪除表A和B中的行,並根據需要從表C中刪除一行。 – Hovo 2014-12-19 00:36:58

+0

@霍沃我知道觸發器是一種選擇,但希望有更好的解決方案 – 12preschph 2014-12-19 00:47:09

回答

5

我建議兩個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列中的一個被更新時才啓動,並且只有在結果都是NULL時才觸發。

  • 觸發器函數很簡單:刪除行並返回NULL以取消現在無效的級聯UPDATE

+0

我希望所有的答案都是這樣的質量。丹科! – Matthieu 2016-05-19 10:09:06