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(經理)。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 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);
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);
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;
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 MATCHED | ON 條件成立(雙方皆有) | 可接多個 AND 條件 分支,順序優先匹配 |
WHEN NOT MATCHED | 來源有、目標無 | 通常用 INSERT |
WHEN NOT MATCHED BY SOURCE | 目標有、來源無 | DB2 11.5+ 支援,可對目標獨有列執行 UPDATE/DELETE |
SIGNAL SQLSTATE |
主動拋出使用者定義錯誤 | SQLSTATE '70xxx' 為使用者自訂範圍 |
ELSE IGNORE |
以上條件皆不符合時略過 | 防止「無法處理的情況」導致語句失敗 |
MERGE 以聲明式單一陳述式取代多條 DML,不僅程式碼簡潔、可維護性高,更能確保同步邏輯的原子一致性。善用條件分支、SIGNAL 異常攔截與 ELSE IGNORE 兜底,即可應對極其複雜的資料同步需求。