2013年11月18日 星期一

MERGE INTO

MERGE INTO命令是Oracle9i /SQL SERVER 2008開始提供的新語法,用以合併UPDATEINSERT命令,UPSERT功能,當資料表中無此資料時(即無法匹配)可執行INSERT,反之則執行UPDATEDELETE10g以上功能)。語法如下:
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      --資料[存在]-執行UPDATEA03已存在,薪水異動。
  UPDATE
     SET U.SALARY = S.SALARY          
WHEN NOT MATCHED THEN  --資料[不存在]-執行INSERTEA05不存在,執行新增。
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將發生錯誤,9iMATCHED / NOT MATCHED兩部分必須同時存在才可,因此在來源與目標連結中,須進資料限縮以促使僅可符合MATHCD部分;而另外NOT MATHCH之必要語法中,則刻意INSERT完全不合理之資料值即可,可自行嘗試。

沒有留言:

張貼留言