2010年11月23日 星期二

僅變更來源表格中相符欄位的紀錄:UPDATE VS. MERGE INTO

從 B Table 將資料更新到 A Table的方式,大都會這樣寫:

UPDATE A 
   SET A.CODE = (SELECT DISTINCT (CODE)
                     FROM B
                    WHERE A.CODE_1 = B.CODE_1
                      AND A.CODE_2 = B.B_CODE_2)

但有個缺點是如果B與A若有沒有相符的紀錄,即在A表格中不符合 A.A_CODE = B.A_CODE & A.B_CODE = B.B_CODE 條件的紀錄,就會被更新成NULL;為了避免這種情況,我們可以加上NVL()函式跳過不相符的紀錄被更新:


UPDATE A 
   SET A.CODE = NVL((SELECT DISTINCT (CODE)
                     FROM B
                    WHERE A.CODE_1 = B.CODE_1
                      AND A.CODE_2 = B.CODE_2), A.CODE)

Oracle 在 9i 之後的版本新增一個 MERGE 的功能,在語意以及速度方面上更勝一籌:

  MERGE INTO A
  USING  B
  ON (A.CODE_1 = B.CODE_1 AND A.CODE_2 = B.CODE_2)
  WHEN MATCHED THEN
    UPDATE SET A.CODE = B.CODE;

語意上就更接近口語化,程式碼也容易變得簡潔。且不止於此,既然有 MATCHED,也就會有 NOT MATCHED,多增加了分支判斷的功能。假設我們想把不符條件的資料記錄到另外一個Table中,就可這樣寫:

MERGE INTO A
  USING  B
  ON (A.CODE_1 = B.CODE_1 AND A.CODE_2 = B.CODE_2)
  WHEN MATCHED THEN
    UPDATE SET A.CODE = B.CODE;
  WHEN NOT MATCHED THEN
INSERT INTO FAIL_REC VALUES (A.CODE_1, A,CODE_2);

分享囉~

沒有留言:

張貼留言