39

来自postgresql 文档

RESTRICT 防止删除引用的行。NO ACTION 表示如果在检查约束时仍然存在任何引用行,则会引发错误;如果您不指定任何内容,这是默认行为。(这两种选择的本质区别在于 NO ACTION 允许将检查推迟到事务的后期,而 RESTRICT 不允许。)

让我们检查一下。创建父子表:

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

填充一些数据:

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

并且测试确实检查确实延迟了:

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

在第一次删除完整性被破坏后,第二次它会被恢复。但是,第一次删除时执行失败。

更新相同:

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

在删除的情况下,我可以交换语句以使其工作,但在更新的情况下,我无法执行它们(可以通过删除两行并插入新版本来实现)。

许多数据库在 RESTRICT 和 NO ACTION 之间没有任何区别,而 postgres 则假装不这样做。它(仍然)是真的吗?

4

1 回答 1

35

仅当您将约束定义为DEFERRABLE使用INITIALLY DEFERREDorINITIALLY IMMEDIATE模式时,才会出现差异。

SET CONSTRAINTS

于 2013-02-17T13:42:31.983 回答