複数の更新処理をまとめたい?SQL Server MERGE文でINSERT・UPDATE・DELETEを1文で実現する方法
SQL Serverには、INSERT・UPDATE・DELETEを1つの命令にまとめて実行できるMERGE文があります。
データ同期やマスタ更新のように、「存在すれば更新、なければ追加」という処理を簡潔に書ける便利な構文です。
この記事では、MERGE文の基本構文と実行の流れ、実務での活用パターン、そして使用時の注意点を初心者向けにわかりやすく解説します。
目次
MERGE文とは?基本の考え方
複数操作を1つのSQLでまとめる
通常、データを比較して「存在すればUPDATE、なければINSERT」といった処理を行う場合、2つ以上のSQL文が必要です。
しかしMERGE文を使えば、それらを1回の命令でまとめて実行できます。
特に、データの同期処理・定期的なマスタ更新・外部システム連携で非常に便利です。
基本イメージ
MERGE文は、ターゲット(更新先)テーブルとソース(比較元)テーブルを突き合わせ、行ごとに条件を判断して処理します。
処理イメージ:
- データが存在する → UPDATE
- 存在しない → INSERT
- 不要なデータ → DELETE
この一連の流れを1文で記述できるのがMERGE文です。
MERGE文の基本構文
MERGE ターゲットテーブル AS T
USING ソーステーブル AS S
ON T.キー列 = S.キー列
WHEN MATCHED THEN
UPDATE SET T.列1 = S.列1, T.列2 = S.列2
WHEN NOT MATCHED BY TARGET THEN
INSERT (列1, 列2) VALUES (S.列1, S.列2)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
この構文では、ONで照合条件を指定し、行ごとに一致・不一致を判定して処理を分岐します。
INSERT・UPDATE・DELETEを1文で処理する例
社員マスタの同期処理例
MERGE INTO Employees AS T
USING EmployeeSource AS S
ON T.EmployeeID = S.EmployeeID
WHEN MATCHED THEN
UPDATE SET
T.Name = S.Name,
T.Department = S.Department,
T.Salary = S.Salary
WHEN NOT MATCHED BY TARGET THEN
INSERT (EmployeeID, Name, Department, Salary)
VALUES (S.EmployeeID, S.Name, S.Department, S.Salary)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
このSQLでは、EmployeeSource(新データ)をもとに Employees テーブルを更新します。
存在すれば更新、なければ追加、不要なら削除する一連の処理を1つのMERGE文で完結できます。
条件を限定して部分更新する
WHEN MATCHEDに条件を追加して、特定のケースだけ更新することも可能です。
WHEN MATCHED AND T.Salary <> S.Salary THEN
UPDATE SET T.Salary = S.Salary;
このように条件を組み合わせることで、柔軟な差分更新ができます。
実務での活用パターン
1. マスタデータの定期更新
毎日や毎週、最新のマスタデータを本番環境に反映する際に、MERGE文を使えば更新漏れを防ぎつつ効率的に同期できます。
2. 外部システムからのデータ取り込み
外部システムから取り込んだデータを一時テーブルに格納し、MERGEで本番テーブルと同期する方法が一般的です。
3. 差分更新バッチ処理
夜間バッチなどで大量データの差分を更新する際、MERGE文を使うと複数のUPDATE・INSERT文を1つにまとめられるため、処理速度と可読性が向上します。
使用時の注意点とベストプラクティス
1. 同時実行による競合に注意
MERGE文は複数操作を同時に行うため、並行実行時にロック競合が発生する可能性があります。
特に大規模テーブルではトランザクション分離レベルを適切に設定しましょう。
2. DELETEの使用を慎重に
WHEN NOT MATCHED BY SOURCE THEN DELETE は非常に強力ですが、誤って削除する危険もあります。
実運用ではまず削除対象をSELECTで確認してから実行するようにしましょう。
SELECT * FROM Employees
WHERE EmployeeID NOT IN (SELECT EmployeeID FROM EmployeeSource);
3. OUTPUT句で変更結果を確認する
MERGE文ではOUTPUT句を使って、どの処理(INSERT/UPDATE/DELETE)が行われたかを確認できます。
MERGE INTO Employees AS T
USING EmployeeSource AS S
ON T.EmployeeID = S.EmployeeID
WHEN MATCHED THEN
UPDATE SET T.Name = S.Name
WHEN NOT MATCHED BY TARGET THEN
INSERT (EmployeeID, Name) VALUES (S.EmployeeID, S.Name)
OUTPUT $action AS 操作, inserted.*, deleted.*;
この結果をログテーブルに記録すれば、更新履歴を自動的に取得することも可能です。
4. バージョンによる挙動差に注意
SQL Server 2008以降でMERGE文がサポートされていますが、古いバージョンでは一部の構文(OUTPUT句など)が使用できません。
運用環境のバージョンに合わせた確認が必要です。
まとめと次のステップ
学んだ内容の整理
- MERGE文はINSERT・UPDATE・DELETEを1文で実行できる統合構文。
- データ同期・マスタ更新・差分更新処理などで効果的。
- DELETE使用時や同時実行には注意し、安全運用にはSELECTとトランザクションを併用。
- OUTPUT句で実行結果をログ化できる。
参考リンク

0 件のコメント:
コメントを投稿