SQLServerでデータの有無でINSERTとUPDATEを判断する

SQLServer

データをテーブルへ登録する際に、対象データの存在確認のためにSELECT文を発行し、対象データが存在しなければINSERT文を発行、対象データが存在すればUPDATE文を発行することがあると思いますが、この一連の処理を1文で記述する方法を紹介します。

コーディング例

BEGIN
  CREATE TABLE #社員
  (
     [社員NO]  INT
    ,[氏名]    VARCHAR(10)
  );

  INSERT INTO #社員
  VALUES
     (1,'佐藤')
    ,(2,'山田')
    ,(3,'斉藤')
  ;

  MERGE INTO 
    #社員 AS A
  USING (
    SELECT
       2       AS [社員NO]
      ,'山本'  AS [氏名]
    ) B
    ON (A.社員NO = B.社員NO)
  WHEN MATCHED THEN
    UPDATE
    SET
      [氏名] = B.[氏名]
  WHEN NOT MATCHED THEN
    INSERT([社員NO],[氏名])
    VALUES
      (B.[社員NO],B.[氏名])
  ;

  SELECT * FROM #社員;

  DROP TABLE #社員;
END

実行結果

社員NO 氏名
1 佐藤
2 山本
3 斉藤

15~16行目の「MERGE INTO #社員 AS A」で検索対象のテーブルを定義し、別名Aとします。
17~21行名の「USING (SELECT 2 AS [社員NO],’山本’ AS [氏名]) B」で、追加/更新データを定義し、別名Bとします。
22行目の「ON A.社員NO = B.社員NO」で検索キーを定義します。
23行目の「WHEN MATCHED THEN」では、検索対象テーブル(A)に追加/更新データ(B)の社員NOが存在した場合の処理を記述します。
24~26行目の「UPDATE SET [氏名] = B.[氏名]」では、更新処理を定義します。通常のUPDATE文に比べると更新テーブル名やWHERE句が省略できます。
27行目の「WHEN NOT MATCHED THEN」では、検索対象テーブル(A)に追加/更新データ(B)の社員NOが存在しない場合の処理を記述します。
28~30行目の「INSERT([社員NO],[氏名]) VALUES (B.[社員NO],B.[氏名])」では、追加処理を定義します。通常のINSERT文に比べると追加テーブル名が省略できます。
通常、SELECT文とINSERT/UPDATE文の2回SQLを発行するところを、1回のSQL文の発行にすることで若干の高速化が期待できるのではないでしょうか。

以上、「SQLServerでデータの有無でINSERTとUPDATEを判断する」の紹介でした。