blu*_*ubb 5 postgresql unique-constraint
我有一列sort_order具有唯一约束的列。以下SQL在Postgres 9.5上失败:
UPDATE test
SET sort_order = sort_order + 1;
-- [23505] ERROR: duplicate key value violates unique constraint "test_sort_order_key"
-- Detail: Key (sort_order)=(2) already exists.
Run Code Online (Sandbox Code Playgroud)
显然,如果sort_order值在更新之前是唯一的,则在更新之后它们仍将是唯一的。为什么是这样?
相同的语句在Oracle和MS SQL上工作正常,但在MySQL和SQLite上失败。
这是SQL小提琴的完整设置代码:
DROP TABLE IF EXISTS test;
CREATE TABLE test (
val TEXT,
sort_order INTEGER NOT NULL UNIQUE
);
INSERT INTO test
VALUES ('A', 1), ('B', 2);
Run Code Online (Sandbox Code Playgroud)
Postgres决定IMMEDIATELY在与SQL标准建议不同的时间检查类型的约束。
具体来说,SET CONSTRAINTS各州的文件(重点是我的):
当插入或修改一行时(不在语句末尾),始终会立即检查NOT NULL和CHECK约束。还可以立即检查尚未声明为DEFERRABLE的唯一性和排除约束。
Postgres选择使用会导致临时冲突sort_order且立即失败的计划执行此查询。请注意,这意味着对于相同的架构和相同的数据,根据执行计划,相同的查询可能会工作或失败。
您必须制作约束DEFERRABLE或DEFERRABLE INITIALLY DEFERRED,这会延迟对约束的验证,直到事务结束或SET CONSTRAINTS ... IMMEDIATE执行语句为止。
| 归档时间: |
|
| 查看次数: |
502 次 |
| 最近记录: |