web-dev-qa-db-ja.com

単一のクエリを使用して挿入または更新する方法は?

主キーと自動インクリメントされた名前の列IDを持つテーブルテストがあります。レコードがない場合にのみ新しいレコードを挿入したい。

入力はid = 30122で、name = johnです。

iD 30122のレコードがある場合は、name列をjohnに更新します。レコードがない場合は、新しいレコードを挿入します。

私は2つのクエリを使用して行うことができます

select * from test where id=30122

いくつかのレコードがある場合は、update test set name='john' where id=3012

またはレコードがない場合は、使用できます

insert into test(name) values('john')

しかし、私は単一のクエリを使用したいと思いましたか?

誰かが可能かどうかを教えてもらえますか?

29
SpringLearner

あなたはこれを試すことができます

IF EXISTS(select * from test where id=30122)
   update test set name='john' where id=3012
ELSE
   insert into test(name) values('john');

パフォーマンス向上のための他のアプローチは

update test set name='john' where id=3012
IF @@ROWCOUNT=0
   insert into test(name) values('john');

また スキーマのプレフィックスを開始するためにこの悪い習慣を読んでください

46
vijayp

SQL Server 2008以降を想定すると、 MERGE を使用できます。

テーブル

CREATE TABLE dbo.Test
(
    id integer NOT NULL,
    name varchar(30) NULL,

    CONSTRAINT PK_dbo_Test__id
        PRIMARY KEY CLUSTERED (id)
);

クエリ

MERGE dbo.Test WITH (SERIALIZABLE) AS T
USING (VALUES (3012, 'john')) AS U (id, name)
    ON U.id = T.id
WHEN MATCHED THEN 
    UPDATE SET T.name = U.name
WHEN NOT MATCHED THEN
    INSERT (id, name) 
    VALUES (U.id, U.name);

SERIALIZABLEヒントは 同時実行性が高い場合の正しい操作 に必要です。

Michael J. Swartによる一般的な方法の比較は、次の場所にあります。

神話:同時更新/ソリューションの挿入

17