2

フィールドを持つテーブルがあります: name|...|start_date|end_date

私のコードは次のとおりです。

select .... 'check for period intersection
insert .... 'if check succesfull insert new row

このコードは 1 回のトランザクションで。2 人のユーザーが同じフィールド (およびピリオドが交差する) で同時に新しいレコードを挿入しようとすると、2 つのレコードが挿入されます。しかし、私はその挿入を避けたいです。最初のユーザーが挿入する必要があり、他のユーザーが競合する必要があります。どうすればできますか?

PS私はIBM DB2を使用しています

4

3 に答える 3

0

UKを使用するか、更新を選択できます。

select .... 'check for period intersection FOR UPDATE WITH RS USE AND KEEP UPDATE LOCKS

更新:次の方法で選択する前に、テーブル全体をロックしてみてください。

LOCK TABLE TABLE_NAME IN EXCLUSIVE MODE

このように、2番目のトランザクションは、前のトランザクションがコミットするのを待ってから選択します。EXCLUSIVE MODEは、更新と挿入だけでなく、selectステートメントもロックします。

更新2:「期間の交差をチェック」が挿入先のテーブルと同じテーブルの列のみを使用する場合は、選択する代わりに、テーブルに制約チェックを追加します。http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=%2Fcom.ibm.db2.udb.admin.doc%2Fdoc%2Ft0004984.htmを参照してください。

于 2012-05-23T10:52:04.433 に答える
0

selectからデータを取得するクエリを挿入します。選択した値を選択すると、挿入する必要のあるデータが表示されます。where句は条件をチェックでき、チェックが失敗した場合はnullを返す必要があります。したがって、ID5がテーブルにない場合に入力したい場合

  Insert into test1(val) select "test" from (select case when id = 5 then null else 5 end '1' from sysP where id =5) aa

このクエリは、テーブルtest1にテストを挿入します。id=5はsysPテーブルにありません

于 2012-05-23T11:03:52.193 に答える
0

MERGEいくつかのエラー発生と組み合わせると、まさにあなたが望むもののように聞こえます。Linux/Unix/Windows で DB2 を使用していると思いますがMERGE、v9.1 からメインフレーム DB2 も使用しています。

MERGE INTO YOUR_TABLE YT
USING (
        VALUES ('val1', 'val2', 'val3')
    ) MG(v1, v2, v3)
 ON (TY.v1 = MG.v1)
WHEN MATCHED 
    SIGNAL SQLSTATE '70001'
    SET MESSAGE_TEXT = 'Record already exists!'
WHEN NOT MATCHED THEN
   INSERT(v1, v2, v3)
   VALUES(MG.v1, MG.v2, MG.v3
ELSE IGNORE;

このUSING句は、提供された値 (ここにあるように) と共に使用することも、サブ選択にすることもできます。上でリンクした Information Center の Merge ページに、他の例があります。

于 2012-05-23T14:05:58.797 に答える