41

私のコード (Java) から、コードの実行後にデータベース (DB2) に行が存在することを確認したいと考えています。

私のコードは現在、を実行し、select結果が返されない場合は を実行しinsertます。マルチスレッド環境で実行すると同時実行性の問題が発生するため、このコードはあまり好きではありません。

私がやりたいことは、このロジックを Java コードではなく DB2 に入れることです。DB2 にはinsert-or-updateステートメントがありますか? または、私が使用できるようなものはありますか?

例えば:

insertupdate into mytable values ('myid')

それを行う別の方法は、おそらく常に挿入を実行して「SQLコード-803主キーが既に存在します」をキャッチすることですが、可能であればそれを避けたいと思います。

4

5 に答える 5

43

はい、DB2 には、UPSERT (更新または挿入) を行う MERGE ステートメントがあります。

MERGE INTO target_table USING source_table ON match-condition
{WHEN [NOT] MATCHED 
          THEN [UPDATE SET ...|DELETE|INSERT VALUES ....|SIGNAL ...]}
[ELSE IGNORE]

見る:

http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.ibm.db2.udb.admin.doc/doc/r0010873.htm

https://www.ibm.com/support/knowledgecenter/en/SS6NHC/com.ibm.swg.im.dashdb.sql.ref.doc/doc/r0010873.html

https://www.ibm.com/developerworks/community/blogs/SQLTips4DB2LUW/entry/merge?lang=en

于 2008-12-01T09:23:09.637 に答える
19

DB2 INSERT OR UPDATE のワンライナーが本当に必要だったので、このスレッドを見つけました。

次の構文は、別の一時テーブルを必要とせずに機能するようです。

VALUES() を使用してテーブル構造を作成することで機能します。SELECT * は余剰のようですが、それがないと構文エラーが発生します。

MERGE INTO mytable AS mt USING (
    SELECT * FROM TABLE (
        VALUES 
            (123, 'text')
    )
) AS vt(id, val) ON (mt.id = vt.id)
WHEN MATCHED THEN
    UPDATE SET val = vt.val
WHEN NOT MATCHED THEN
    INSERT (id, val) VALUES (vt.id, vt.val)
;

複数の行を挿入する必要がある場合は、残りを複製することなく VALUES 部分を繰り返すことができます。

VALUES 
    (123, 'text'),
    (456, 'more')

結果は、おそらくアトミック操作として 1 つまたは複数の行を INSERT または UPDATE できる単一のステートメントです。

于 2014-05-21T13:26:27.820 に答える
3

もう 1 つの方法は、この 2 つのクエリを実行することです。MERGE ステートメントを作成するよりも簡単です。

update TABLE_NAME set FIELD_NAME=xxxxx where MyID=XXX;

INSERT INTO TABLE_NAME values (MyField1,MyField2) 
WHERE NOT EXISTS(select 1 from TABLE_NAME where MyId=xxxx);

MyId が存在する場合、最初のクエリは必要なフィールドを更新するだけです。2 番目は、MyId が存在しない場合、行を db に挿入します。

その結果、クエリの 1 つだけがデータベースで実行されます。

于 2014-04-22T15:34:20.847 に答える