From postgresql documentation:
RESTRICT prevents deletion of a referenced row. NO ACTION means that if any referencing rows still exist when the constraint is checked, an error is raised; this is the default behavior if you do not specify anything. (The essential difference between these two choices is that NO ACTION allows the check to be deferred until later in the transaction, whereas RESTRICT does not.)
Lets check it. Create parent and child table:
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 );
Populate some data:
insert into parent values(1); insert into child values(5, 1);
And test does check is really deffered:
BEGIN; delete from parent where id = 1; -- violates foreign key constraint, execution fails delete from child where parent_id = 1; COMMIT;
After first delete integrity was broken, but after second it would be restored. However, execution fails on first delete.
Same for update:
BEGIN; update parent set id = 2 where id = 1; -- same as above update child set parent_id = 2 where parent_id = 1; COMMIT;
In case of deletes I can swap statements to make it work, but in case of updates I just can't do them (it is achivable via deleting both rows and inserting new versions).
Many databases don't make any difference between RESTRICT and NO ACTION while postgres pretends to do otherwise. Is it (still) true?
For an ON DELETE or ON UPDATE that is not specified, the default action is always NO ACTION . As the default, an ON DELETE NO ACTION or ON UPDATE NO ACTION clause that is specified explicitly does not appear in SHOW CREATE TABLE output or in tables dumped with mysqldump.
The CASCADE option directs the DBMS Server to revoke the specified privileges plus all privileges and objects that depend on the privileges being revoked. The RESTRICT option directs the DBMS Server not to revoke the specified privilege if there are any dependent privileges or objects.
The ON DELETE clause says that if a particular primary key ID value in the CUSTOMERS table is deleted, this action shall be prevented (this is the "restrict" part) if there is any row in the ORDERS table which has a foreign key that matches the value of the CUSTOMER table ID value.
ON UPDATE defaults to RESTRICT, which means the UPDATE on the parent record will fail. 2) ON DELETE action defaults to RESTRICT, which means the DELETE on the parent record will fail. ON UPDATE CASCADE will update all referencing child records when the parent record is updated.
The difference only arises when you define a constraint as DEFERRABLE
with an INITIALLY DEFERRED
or INITIALLY IMMEDIATE
mode.
See SET CONSTRAINTS
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With