2014-12-19 26 views
6

Ho il seguente esempio:CASCADE DELETE su due vincoli di chiave esterna

Table A 
    -some_id 

Table B 
    -another_id 

Table C 
    -some_id_fk 
    -another_id_fk 

voglio cascata fila su Table C se entrambi some_id e another_id vengono eliminati dalle rispettive tabelle.

Come è possibile creare una riga nella tabella C in cascata se si eliminano due chiavi esterne?

Se uno degli FK viene eliminato, la riga interessata dovrebbe passare a un valore nullo nella colonna che fa riferimento a tale chiave esterna.

+2

Cosa dovrebbe succedere quando una delle righe di riferimento viene cancellata? Impostare l'FK su 'NULL'? –

+2

Scrivere due trigger ON DELETE per le tabelle A e B per rimuovere una riga dalla tabella C se necessario. O meglio scrivere due procedure per eliminare le righe dalla tabella A e B e rimuovere una riga dalla tabella C se necessario. – Hovo

+0

@Hovo Sapevo che i trigger erano un'opzione ma speravo in una soluzione migliore – 12preschph

risposta

5

suggerisco due foreign key constraints with ON DELETE SET NULL e un trigger che si prende cura di tutto il resto

Tavoli:

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) 
); 

trigger:

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.

  • Assicurarsi di avere una colonna PK surrogata per la tabella di connessione. (a_id, b_id) non può essere comunque il PK, perché ciò non consentirebbe NULL in entrambi. Aggiungi invece un UNIQUE constraint, che consente i valori NULL.

  • Il trigger è ottimizzato per le prestazioni e si attiva solo quando una delle due colonne FK viene aggiornata e solo quando risulta che entrambi sono NULL.

  • La funzione di innesco è banale: cancella la riga e restituisce NULL per annullare l'ora vuota a cascata UPDATE.

+0

Vorrei che tutte le risposte fossero di quella qualità. Danke! – Matthieu