2012-04-05 9 views
1

この形式の数値は、2012-01(現在の年は2012)、01はデータベースのフィールドの最大値を1だけ増やしたものです。毎年その数値は0にリセットされます。oracleデータベースに同じ値を2回挿入することを防止する

しかし、同じ操作を同時に実行しようとするユーザーが2人いる場合、両方の値が同じであるため、同じ番号がデータベースに2回挿入されます。

私はシーケンスを作成することを考えましたが、それは毎年シーケンスをリセットするジョブを必要とし、次の番号を取得する前にロックを行う方法があれば好きでしょう。

ありがとうございました。

+0

このAsk Tomリンクを参照してください。http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:4343369880986シーケンスをリセットしようとしているので基本的にはギャップのないアプローチを試みています。これは、パフォーマンスの影響(並行性がうまく調整されないように行をロックする)のために非常に推奨されていません。 –

答えて

2

カウンタとして使用されるフィールドを格納する場所は指定しません。しかし、おそらくSELECT FOR UPDATEステートメントを使用することは可能です。

カウンタフィールドの値を1増やす前に、SELECT FOR UPDATEを使用してそのレコードをロックできます。次にカウンタを更新します。

このような何かを、テーブルを想定したことだけで1レコードを持っている:1つのセッション(ユーザーが)SELECT FOR UPDATEとまだコミットまたはロールバックを行っている場合

SELECT * 
FROM CounterTable 
FOR UPDATE; 

UPDATE CounterTable 
SET Counter = Counter + 1; 

COMMIT; 

を、他のセッション(ユーザー)SELECT FOR UPDATEをやってロックを取得できるようにするのをブロックします。これにより、2人のユーザーが同じ番号を取得できなくなります。

+0

ありがとう、これは素晴らしい仕事をした –

5

CREATE UNIQUE INDEX index_name ON table_name(column_name);

又は

ALTERテーブルtable_nameのADD制約CONSTRAINT_NAME UNIQUE(COLUMN_NAME)。

+0

ありがとう、それはクールなようですが、私はこの特定の例外(ユニークなconstaint違反)を私の列の次の行を挿入するために再びキャッチすることができますか? –

+1

通常、プログラムのフローを制御する手段として例外を使用することはお勧めしません。 –

+0

@RemkoJansen、私は必ずしもあなたに「一般的に」同意するわけではありませんが、この場合あなたは正しいです。 PK違反の有無に関わらず、OPがシーケンスを使用している必要があります。 – Ben

関連する問題