1つのステートメントを使用してSQL ServerでUPSERT
または言い換えるとUPDATE if records exists Else enter new record
操作を使用する方法を知りたいですか。
この例は、Oracleでこれを実現する方法を示しています Here ただし、SQL Server
に存在しないDual
テーブルを使用します。
だから、SQL Serverの代替案(ストアドプロシージャなし)してください?
多くの人がMERGE
を使用することを提案しますが、私はあなたに警告します。デフォルトでは、複数のステートメント以上の並行性と競合状態からあなたを保護しませんが、他の危険をもたらします:
http://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/
この「より単純な」構文が利用可能であっても、私はこのアプローチを好んでいます(簡潔にするためにエラー処理は省略されています)。
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
UPDATE dbo.table SET ... WHERE PK = @PK;
IF @@ROWCOUNT = 0
BEGIN
INSERT dbo.table(PK, ...) SELECT @PK, ...;
END
COMMIT TRANSACTION;
多くの人がこの方法を提案します:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
IF EXISTS (SELECT 1 FROM dbo.table WHERE PK = @PK)
BEGIN
UPDATE ...
END
ELSE
BEGIN
INSERT ...
END
COMMIT TRANSACTION;
ただし、これにより、テーブルを2回読み取って更新する行を見つける必要がある場合があります。最初のサンプルでは、行を1回だけ見つける必要があります。 (どちらの場合も、最初の読み取りで行が見つからない場合、挿入が発生します。)
他の人はこの方法を提案します:
BEGIN TRY
INSERT ...
END TRY
BEGIN CATCH
IF ERROR_NUMBER() = 2627
UPDATE ...
END CATCH
ただし、これは、ほとんどすべての挿入が失敗するまれなシナリオを除き、そもそも防止できた例外をSQL Serverにキャッチさせる以外の理由ではるかに高価な場合、問題があります。私もここで証明します:
単一のステートメントを持つことで得られると思うものがわからない。何も得られないと思います。 MERGE
は単一のステートメントですが、実際には複数の操作を実行する必要があります。