首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

DB2 MERGE 語句完全指南:Upsert、條件更新/刪除、異常拋出與複雜同步邏輯實戰

     編輯:DB2 教學

MERGE 是 DB2 強大的「單一陳述式同步兩表資料」工具,能在一次掃描中完成 INSERT/UPDATE/DELETE 三種操作,並支援條件判斷、錯誤訊號拋出、ELSE IGNORE 兜底。本文從基礎語法進階至複雜業務場景,附完整範例與效能建議。

一、核心語法架構

MERGE INTO 目標表 AS T
USING 來源表/查詢 AS S
ON T.key = S.key
WHEN MATCHED [AND 條件] THEN UPDATE SET ...
WHEN NOT MATCHED [AND 條件] THEN INSERT ...
[ELSE IGNORE];

二、基礎範例:經理表併入員工表

場景

  • 目標表 EMPLOYE(員工)、來源表 MANAGER(經理)。
  • 王五在兩表皆存在(升遷),趙六僅在 MANAGER。
  • 需求:存在則更新薪資,不存在則插入。

傳統兩步法

UPDATE EMPLOYE e SET salary = (SELECT salary FROM MANAGER m WHERE m.id = e.id)
WHERE e.id IN (SELECT id FROM MANAGER);

INSERT INTO EMPLOYE (id, name, salary)
SELECT id, name, salary FROM MANAGER
WHERE id NOT IN (SELECT id FROM EMPLOYE);

MERGE 單一陳述式

MERGE INTO EMPLOYE AS e
USING MANAGER AS m
ON e.employeeid = m.managerid
WHEN MATCHED THEN UPDATE SET e.salary = m.salary
WHEN NOT MATCHED THEN INSERT VALUES (m.managerid, m.name, m.salary);

三、進階條件控制

1. 條件更新:僅當來源薪資較高才更新

MERGE INTO EMPLOYE AS e
USING MANAGER AS m
ON e.employeeid = m.managerid
WHEN MATCHED AND e.salary < m.salary THEN UPDATE SET e.salary = m.salary
WHEN NOT MATCHED THEN INSERT VALUES (m.managerid, m.name, m.salary);

2. 異常資料拋出錯誤:來源薪資不應低於目標

MERGE INTO EMPLOYE AS e
USING MANAGER AS m
ON e.employeeid = m.managerid
WHEN MATCHED AND e.salary < m.salary THEN UPDATE SET e.salary = m.salary
WHEN MATCHED AND e.salary > m.salary THEN
    SIGNAL SQLSTATE '70001' SET MESSAGE_TEXT = '來源薪資低於目標,資料異常'
WHEN NOT MATCHED THEN INSERT VALUES (m.managerid, m.name, m.salary)
ELSE IGNORE;

3. 反向刪除:來源薪資較低則刪除目標列

MERGE INTO EMPLOYE AS e
USING MANAGER AS m
ON e.employeeid = m.managerid
WHEN MATCHED AND e.salary < m.salary THEN UPDATE SET e.salary = m.salary
WHEN MATCHED AND e.salary > m.salary THEN DELETE
WHEN NOT MATCHED THEN INSERT VALUES (m.managerid, m.name, m.salary)
ELSE IGNORE;

四、關鍵字句詳細說明

子句 功能 備註
WHEN MATCHEDON 條件成立(雙方皆有)可接多個 AND 條件 分支,順序優先匹配
WHEN NOT MATCHED來源有、目標無通常用 INSERT
WHEN NOT MATCHED BY SOURCE目標有、來源無DB2 11.5+ 支援,可對目標獨有列執行 UPDATE/DELETE
SIGNAL SQLSTATE 主動拋出使用者定義錯誤 SQLSTATE '70xxx' 為使用者自訂範圍
ELSE IGNORE 以上條件皆不符合時略過 防止「無法處理的情況」導致語句失敗

五、效能與最佳實務

  1. ON 條件欄位建立索引(目標表與來源表),大幅降低連接成本。
  2. 來源資料集盡量小:用 CTE/子查詢預先過濾,避免全表掃描。
  3. 避免觸發器連鎖:MERGE 會觸發目標表的 INSERT/UPDATE/DELETE 觸發器,大量資料時考慮分批或暫停觸發器。
  4. 鎖升級風險:大量 MERGE 可能導致表鎖,生產環境建議在維護窗口執行或分區處理。
  5. 原子性:單一 MERGE 為單一交易,全成功或全失敗;需分批認可時請拆分多條 MERGE。

六、適用場景總結

  • ETL 增量載入:Stage 表 → 目標表(Upsert)。
  • 主資料同步:MDM 主檔 → 各業務庫。
  • 緩慢變維度 (SCD) Type 1:直接覆蓋歷史屬性。
  • 資料清洗修正:條件式 UPDATE/DELETE + 記錄異常。

小結

MERGE 以聲明式單一陳述式取代多條 DML,不僅程式碼簡潔、可維護性高,更能確保同步邏輯的原子一致性。善用條件分支、SIGNAL 異常攔截與 ELSE IGNORE 兜底,即可應對極其複雜的資料同步需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved