2012-04-16 8 views
0

xとyに固有の制約があるこのような表があるとします。SQLの更新を注文しました

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

私は、UPDATE文で一定量の行のセットの中の値xとyを増やすことをお勧めします。私はそれらを両方とも1ずつ増やしているとします。UPDATEがIDの順番に従っているように見え、1,2行目を更新した後にエラーが出ます。次の行に衝突します。まだ。

私はグーグルで、UPDATEを使用して注文を使用する方法を見つけることができません。それを逆にすることは、私のアプリケーションには十分です。私はまた、セット全体が更新後に一貫していると確信しています。

すべてのソリューションはありますか?アップデートに注文を強制する何らかの方法、または完了するまで制約チェックを延期する方法はありますか?

これはDjangoアプリケーションのためのもので、サポートされているすべてのデータベースと互換性があります。私はいくつかのデータベースが原子的なトランザクションを持っていることを知っています。この問題は起こらないでしょうし、この問題を避けるための機能がいくつかありますが、私は厳密に標準的なSQLソリューションが必要です。

+1

どのDBMS? PostgreSQL?オラクル? DB2? –

+1

ようこそStackOverflowへ。 SQLの質問をするときは、使用しているデータベースのタグも追加すると役に立ちます。それらの間に構文と機能にはさまざまなバリエーションがあり、そうすることでより迅速に役に立つ回答を得ることができます。質問を編集して追加することができます。ありがとう。 :) –

+0

私がobsで述べたように、これはDjangoアプリケーションのためのものであり、サポートされているすべてのデータベースで使用されることを意図しているので、一般的な解決策が優れています。私はテスト用にSQLiteを使って開発していますが、 'a_horse_with_no_name'で与えられた答えから、私は問題がOracleでは起こらないと想定しています。 –

答えて

1

PostgreSQLの場合、主キー制約を「遅延可能」として定義することができ、コミット時にのみ評価されます。

PostgreSQLでは、これは次のようになります。それは、単一のアトミック操作としてUPDATE文を評価するようOracleの場合

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=> 

が、これは必要ではないので、そこに箱から出して動作します。

+0

これはプライマリキーではなく、(x、y)ペアのユニーク制約ですが、私はそのアイデアを得ます。 –

+0

@pjwerneck:ユニーク制約は基本的にプライマリキーと同じです。 –

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 

問題は一切発生しません。

関連する問題