有序的SQL更新

时间:2012-04-16 17:02:21

标签: sql

给定这样的表,其中x和y具有唯一约束。

id,x,y
1, 1,1
2, 1,2
3, 2,3
4, 3,5
..

我希望使用UPDATE语句将一组行中的值x和y增加固定量。假设我将它们都增加1,似乎UPDATE遵循id顺序,并在用1 2更新行后给出错误,因为它与下一行碰撞,2 3,尚未更新为3,4爱好。

谷歌搜索,我找不到强制UPDATE使用订单的方法。反过来对我的应用程序来说已经足够了。在整个更新后,我也确定该集合是一致的。

任何解决方案?某种方法强制订单进入更新,或以任何方式推迟约束检查直到完成?

这适用于Django应用程序,它意味着与所有支持的数据库兼容。我知道有些数据库有原子事务,这个问题不会发生,有些具有避免这个问题的功能,但我需要一个严格标准的SQL解决方案。

2 个答案:

答案 0 :(得分:1)

对于PostgreSQL,您可以将主键约束定义为“可延迟”,然后仅在提交时进行评估。

在PostgreSQL中,这将是这样的:

postgres=>create table foo (
postgres(>    id integer not null,
postgres(>     x integer,
postgres(>     y integer
postgres(>);
CREATE TABLE
postgres=>alter table foo add constraint pk_foo primary key (id) deferrable initially deferred;
ALTER TABLE
postgres=> insert into foo (id, x,y) values (1,1,1), (2,1,1), (3,1,1);
INSERT 0 3
postgres=> commit;
COMMIT
postgres=> update foo set id = id + 1;
UPDATE 3
postgres=> commit;
COMMIT
postgres=> select * from foo;
 id | x | y
----+---+---
  2 | 1 | 1
  3 | 1 | 1
  4 | 1 | 1
(3 rows)
postgres=>

对于Oracle,这不是必需的,因为它会将UPDATE语句评估为单个原子操作,因此在那里开箱即用。

答案 1 :(得分:0)

为了便于参考,MS SQL Server也不会出现问题。 UPDATE是单个原子操作。

ALTER TABLE [table_name]
ADD CONSTRAINT unique_constraint
UNIQUE(x)

ALTER TABLE [table_name]
ADD CONSTRAINT unique_constraint2
UNIQUE(y)

update [table_name]
set x = x+1,
y = y+1

应该没有问题。