MERGE文でデータの存在を確認せずにINSERTまたUPDATEを実行する方法

2019-11-14SQLServer

SQLServerではMERGE文を使うと更新先に該当のキーのデータがあるかないかをIF文で確認したりせずに1行でINSERTもしくはUPDATE文を切り替えて実行することができます。

MERGE文でデータの存在を確認せずにINSERTまたUPDATEを実行する方法

本来、ユニークキーが設定されているテーブルに対してデーターの追加、更新を行う際は、まず該当のデータが存在するかどうかのチェック(一旦SELECT)してからINSERTかUPDATEをIF文で切り替えて実行します。

ところがMERGE文を使えばこの事前チェックなしにINSERTかUPDATEを1行で実行できるようになります。

MERGE文の使い方

以下のSQLが実際のMERGE文の使い方になります。

-----------------------------------------
--コピー元とコピー先のテーブルを生成する
-----------------------------------------
CREATE TABLE #moto_table
(
     no      SMALLINT
    ,name    VARCHAR(20)
    ,age     SMALLINT
)
CREATE TABLE #saki_table
(
     no      SMALLINT
    ,name    VARCHAR(20)
    ,age     SMALLINT
)
 
-----------------------------------------
--コピー元とコピー先のデータを生成する
-----------------------------------------
INSERT INTO #moto_table VALUES( 10, 'モト・太郎さん', 30 );
INSERT INTO #moto_table VALUES( 20, 'モト・次郎さん', 35 );
INSERT INTO #saki_table VALUES( 10, 'サキ・太郎さん', 40 );

-----------------------------------------
--コピー元とコピー先のデータを参照する
-----------------------------------------
SELECT no, name, age FROM #moto_table ORDER BY no
SELECT no, name, age FROM #saki_table ORDER BY no

-----------------------------------------
--コピー元をコピー先にコピーする
-----------------------------------------
MERGE INTO #saki_table AS A
    USING (
           SELECT
                no    AS no
               ,name  AS name
               ,age   AS age
           FROM
               #moto_table
           ) AS B
    ON
    (
        A.no = B.no
    )
    WHEN MATCHED THEN            --キーが一致した時のUPDATE文
        UPDATE SET
             name = B.name
            ,age = B.age
    WHEN NOT MATCHED THEN        --キーが一致しなかった時のINSERT文
        INSERT
        (
             no
            ,name
            ,age
        )
        VALUES
        (
             B.no
            ,B.name
            ,B.age
        )
;

-----------------------------------------
--コピー元とコピー先のデータを参照する
-----------------------------------------
SELECT no, name, age FROM #moto_table ORDER BY no
SELECT no, name, age FROM #saki_table ORDER BY no

-----------------------------------------
--コピー元とコピー先のテーブルを削除する
-----------------------------------------
DROP TABLE #moto_table
DROP TABLE #saki_table

#saki_tableテーブルに#moto_tableテーブルの内容がコピーされていますね。
(削除はされません。)

まとめ

MERGE文を使えばINSERTかUPDATEを1行で実行できるようになリ、ソースコードに無駄なIF文を書く必要がなくなるので大変重宝します。

以上、「MERGE文でデータの存在を確認せずにINSERTまたUPDATEを実行する方法」でした。