1. 程式人生 > >MERGE INTO 目標表 USING 資料來源表 ON(0=1) 的用法

MERGE INTO 目標表 USING 資料來源表 ON(0=1) 的用法

儲存過程中merge into 一般用於增量插入資料,如果是源表全量資料插入目標表常規認為insert into 比merge into 效率更高,

但是資料來源表的資料來源是需要查詢大量關聯表時然後全量錄入目標表時,merge into 後面的匹配條件on(0=1) 可以使插入資料效率更高;

具體的執行效率可以看完成同樣事物Oracle執行時間的長短;

Oracle 9i引入的功能),其語法如下:

MERGE INTO table_name alias1 
USING (table|view|sub_query) alias2
ON (join condition) 
WHEN MATCHED THEN 
    UPDATE table_name 
    SET col1 = col_val1, 
           col2 = col_val2 
WHEN NOT MATCHED THEN 


在一個同時存在Insert和Update語法的Merge語句中,總共Insert/Update的記錄數,就是Using語句中alias2的記錄數

寫法如下:

MERGE INTO T T1
USING (SELECT '1001' AS a,2 AS b FROM dual) T2
ON ( T1.a=T2.a)
WHEN MATCHED THEN
    UPDATE SET T1.b = T2.b
WHEN NOT MATCHED THEN 
    INSERT (a,b) VALUES(T2.a,T2.b);
在Oracle 10g中MERGE有如下一些改進: 
1、UPDATE或INSERT子句是可選的 
2、UPDATE和INSERT子句可以加WHERE子句 
3、在ON條件中使用常量過濾謂詞來insert所有的行到目標表中,不需要連線源表和目標表 
4、UPDATE子句後面可以跟DELETE子句來去除一些不需要的行 


我們通過例項來一一看看如上的新特性 

1. UPDATE或INSERT子句是可選的 
在9i裡由於必須insert into和update都要存在,也就是不是update就是insert,不支援單一的操作,雖然還是可以曲線救國,呵呵 但是有些過於強勢了。而10g裡就是可選了,能符合我們更多的需求了 
比如上面的句子 
我們可以只存在update或者insert 
merge into products p using newproducts np on (p.product_id = np.product_id) 
when matched then 
update set p.product_name = np.product_name 


這裡,如果匹配就更新,不存在就不管了。 

2. UPDATE和INSERT子句可以加WHERE子句 
這也是一個功能性的改進,能夠符合我們更多的需求,這個where的作用很明顯是一個過濾的條件,是我們加入一些額外的條件,對只對滿足where條件的進行更新和insert 
merge into products p using (select * from newproducts) np on (p.product_id = np.product_id) 
when matched then 
update set p.product_name = np.product_name where np.product_name like 'OL%' 


這裡表示只是對product_name開頭是'OL'的匹配上的進行update,如果開頭不是'OL'的就是匹配了也不做什麼事情,insert裡也可以加入where 
比如 
merge into products p using (select * from newproducts) np on (p.product_id = np.product_id) 
when matched then 
update set p.product_name = np.product_name where np.product_name like 'OL%' 
when not matched then 
insert values(np.product_id, np.product_name, np.category) where np.product_name like 'OL%' 

這裡注意比較一下,他們返回的結果行數,是有著差異的。 

3. 在ON條件中使用常量過濾謂詞來insert所有的行到目標表中,不需要連線源表和目標表 


merge into products p using (select * from newproducts) np on (1=0) 
when matched then 
update set p.product_name = np.product_name 
when not matched then 
insert values(np.product_id, np.product_name, np.category) 


這個功能一般不太用,我們的insert into本身就支援這樣的功能,沒有必要使用merge ,但是像插入的每條語句都需要關聯複雜表查詢可以使用這種語法,執行時間更短;

4. UPDATE子句後面可以跟DELETE子句來去除一些不需要的行 

delete只能和update配合,從而達到刪除滿足where條件的子句的紀錄 
merge into products p using (select * from newproducts) np on (p.product_id = np.product_id) 
when matched then 
update set p.product_name = np.product_name delete where p.product_id = np.product_id where np.product_name like 'OL%' 
when not matched then 
insert values(np.product_id, np.product_name, np.category) 


這裡我們達到的目的就是 會把匹配的記錄的prodcut_name更新到product裡,並且把product_name開頭為OL的刪除掉。

merge into也是一個dml語句,和其他的dml語句一樣需要通過rollback和commit 結束事務。