2013-02-17 3 views
13

Von postgresql documentation:Unterschied zwischen RESTRICT und NO ACTION

RESTRICT verhindert das Löschen eines referenzierten Zeile. NO ACTION bedeutet, dass, wenn Zeilen, die referenziert werden, noch vorhanden sind, wenn die Einschränkung aktiviert ist, ein Fehler auftritt; Dies ist das Standardverhalten, wenn Sie nichts angeben. (Der wesentliche Unterschied zwischen diesen beiden Möglichkeiten ist, dass NO ACTION die Prüfung erst später in der Transaktion wird latenten ermöglicht, während nicht einschränkt.)

Ermöglicht es zu überprüfen. Erstellen Eltern und Kind Tabelle:

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

Bestücken einige Daten:

insert into parent values(1); 
insert into child values(5, 1); 

Und Test überprüft wird wirklich DEFFERED:

BEGIN; 
delete from parent where id = 1; -- violates foreign key constraint, execution fails 
delete from child where parent_id = 1; 
COMMIT; 

Nach dem ersten Integrität löschen war gebrochen, aber nach dem zweiten es würde wiederhergestellt werden. Die Ausführung schlägt jedoch beim ersten Löschen fehl.

Das Gleiche gilt für Update:

BEGIN; 
update parent set id = 2 where id = 1; -- same as above 
update child set parent_id = 2 where parent_id = 1; 
COMMIT; 

Bei Löschungen kann ich Aussagen tauschen, damit es funktioniert, aber im Fall von Updates Ich kann sie einfach nicht tun (es ist achivable über beiden Reihen zu löschen und Einfügen neue Versionen).

Viele Datenbanken machen keinen Unterschied zwischen RESTRICT und NO ACTION, während postgres etwas anderes vorgibt. Ist es (immer noch) wahr?

Antwort

14

Der Unterschied tritt nur auf, wenn Sie eine Integritätsbedingung als DEFERRABLE mit einem INITIALLY DEFERRED oder INITIALLY IMMEDIATE Modus definieren.

Siehe SET CONSTRAINTS.