MERGE INTO命令是Oracle9i
/SQL SERVER 2008開始提供的新語法,用以合併UPDATE及INSERT命令,即UPSERT功能,當資料表中無此資料時(即無法匹配)可執行INSERT,反之則執行UPDATE或DELETE(10g以上功能)。語法如下:
MERGE <hint> INTO <table_name>
USING <table_view_or_query>
ON (<condition>)
WHEN MATCHED THEN
<update_clause>
WHEN NOT MATCHED THEN
<insert_clause>
|
MERGE INTO指令在MATCHED情況下可以進行資料異動(UPDATE),可利用此項特性於UPDATE
WITH JOIN上, MSSQL可在UPDATE語法中使用FROM子句,因此撰寫UPDATE
WITH JOIN幾乎與SELECT語法類似,ORACLE則否,UPDATE WITH
JOIN語法上並不直覺問題,如對UPDATE WITH JOIN不熟悉則建議以MERGE
INTO代替。測試資料如下,依資料來源是否為資料表分為2個測試案例,如下:
EMP
DEPT
測試1: (UPSERT)
增加韓大夫(新增)資料,並將邁爵士調薪為60,000(異動)。由於參考資料並非源自其他資料表時(如輸入),則可使用查詢語法以產生衍生資料表(Derived Table)方式,如下:
SQL:
MERGE INTO #EMP
U
USING
(
SELECT 'A05'
EMP_NO, '韓大夫' EMP_NAME, 80000 SALARY, 'IT' DETP_NO
--FROM DUAL
UNION ALL
SELECT 'A03'
EMP_NO, '邁爵士' EMP_NAME, 60000 SALARY, 'MA' DETP_NO
--FROM DUAL
) S
ON (
U.EMP_NO = S.EMP_NO
)
WHEN MATCHED THEN
--資料[存在]-執行UPDATE;A03已存在,薪水異動。
UPDATE
SET U.SALARY = S.SALARY
WHEN NOT MATCHED
THEN --資料[不存在]-執行INSERTE;A05不存在,執行新增。
INSERT (EMP_NO, EMP_NAME, SALARY, DETP_NO)
VALUES (S.EMP_NO, S.EMP_NAME, S.SALARY, S.DETP_NO) ;
測試2: (UPDATE With Join)
將資訊部所有人員調薪20%(異動)。SQL及執行結果如下:
MERGE INTO #EMP
U
USING
(
SELECT DETP_NO
FROM #DEPT_H
WHERE 1=1
AND
DETP_NO ='IT'
) S
ON (
U.DETP_NO = S.DETP_NO
)
WHEN MATCHED THEN
--資料存在-執行UPDATE;
UPDATE
SET U.SALARY = U.SALARY * 1.2;
測試2之語法,ORACLE
9i將發生錯誤,9i中MATCHED / NOT MATCHED兩部分必須同時存在才可,因此在來源與目標連結中,須進資料限縮以促使僅可符合MATHCD部分;而另外NOT MATHCH之必要語法中,則刻意INSERT完全不合理之資料值即可,可自行嘗試。