Da postgresql documentation:Differenza tra LIMITARE e nessuna azione
LIMITANO impedisce cancellazione di una riga di riferimento. NO ACTION significa che se esistono ancora delle righe di riferimento quando il vincolo è selezionato, viene generato un errore; questo è il comportamento predefinito se non si specifica nulla. (La differenza essenziale tra queste due scelte è che nessuna azione permette il controllo da rinviata a più tardi nella transazione, mentre LIMITARE non.)
Lets controllarlo. Creare genitore e tabella figlio:
CREATE TABLE parent (
id serial not null,
CONSTRAINT parent_pkey PRIMARY KEY (id)
);
CREATE TABLE child (
id serial not null,
parent_id serial not null,
CONSTRAINT child_pkey PRIMARY KEY (id),
CONSTRAINT parent_fk FOREIGN KEY (parent_id)
REFERENCES parent (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
);
popolano alcuni dati:
insert into parent values(1);
insert into child values(5, 1);
E prova non di controllo è davvero deffered:
BEGIN;
delete from parent where id = 1; -- violates foreign key constraint, execution fails
delete from child where parent_id = 1;
COMMIT;
Dopo la prima cancellare l'integrità era rotto, ma dopo la seconda sarebbe stato ripristinato. Tuttavia, l'esecuzione non riesce alla prima eliminazione.
Lo stesso vale per l'aggiornamento:
BEGIN;
update parent set id = 2 where id = 1; -- same as above
update child set parent_id = 2 where parent_id = 1;
COMMIT;
In caso di eliminazioni posso scambiare dichiarazioni per farlo funzionare, ma in caso di aggiornamenti non riesco proprio a fare loro (è achivable tramite l'eliminazione di entrambe le file e l'inserimento nuove versioni).
Molti database non fanno alcuna differenza tra RESTRICT e NO ACTION mentre postgres finge di fare diversamente. È (ancora) vero?