除了其他(正确)答案外,在谈到PostgreSQL时,还必须指出:
使用NOT DEFERRABLE,在插入/更新时检查每一行
使用DEFERRABLE(当前为IMMEDIATE),在插入/更新结束时检查所有行
使用DEFERRABLE(当前为DEFERRED),在事务结束时检查所有行
因此,将DEFERRABLE约束设置为IMMEDIATE时,它的行为类似于NOT DEFERRABLE约束,这是不正确的。
让我们详细说明一下这一区别:
CREATE TABLE example(
row integer NOT NULL,
col integer NOT NULL,
UNIQUE (row, col) DEFERRABLE INITIALLY IMMEDIATE
);
INSERT INTO example (row, col) VALUES (1,1),(2,2),(3,3);
UPDATE example SET row = row + 1, col = col + 1;
SELECT * FROM example;
正确输出:
但是如果我们删除DEFERRABLE INITIALLY IMMEDIATE指令,
错误:重复的键值违反了唯一约束“ example_row_col_key”详细信息:键(“ row”,col)=(2,2)已存在。**********错误**********
错误:重复的键值违反了唯一约束“ example_row_col_key” SQL状态:23505详细信息:键(“ row”,col)=(2,2)已存在。
附录 (2017年10月12日)
此行为确实记录在 “兼容性”部分:
而且,PostgreSQL会立即检查不可延展的唯一性约束,而不是在标准声明的结尾处检查。
DEFERRABLE
表明设计者的意图是推迟约束是值得或必要的动作。对于绝大多数数据库约束和标记来说,情况并非如此,因为它们DEFERRABLE
将失去这种有用的区别。