1. 程式人生 > >Merge into語句的使用

Merge into語句的使用

Merge into 用來從一個表中選擇一些資料更新或者插入到另一個表中。而最終是用更新還是用插入的方式取決於該語句中的條件。
如果N條記錄條件符合,就向目標表merge_test1 更新N條記錄。如果有M條記錄不符合要求,就向目標表merge_test1 插入M條記錄。
通過這個merge你能夠在一個SQL語句中對一個表同時執行inserts和updates操作. 當然是update還是insert是依據於你的指定的條
件判斷的,Merge into可以實現用B表來更新A表資料,如果A表中沒有,則把B表的資料插入A表. MERGE命令從一個或多個數據源中
選擇行來updating或inserting到一個或多個表 


語法如下 
MERGE INTO [your table-name] [rename your table here] 
USING ( [write your query here] )[rename your query-sql and using just like a table] 
ON ([conditional expression here] AND [...]...) 
WHEN MATHED THEN [here you can execute some update sql or something else or delete sql] 
WHEN NOT MATHED THEN [execute something else here ! ] 


我們先看看一個簡單的例子,來介紹一個merge into的用法 
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 
when not matched then 
insert values(np.product_id, np.product_name, np.category) 






下面我們簡單的舉一個例子:
SQL> create table merge_test1(a number,b varchar2(20)) 
表已建立。
SQL> create table merge_test2(a number,b varchar2(20)) 
表已建立。
SQL> insert into merge_test1 values(1,'A'); 
已建立 1 行。
SQL> insert into merge_test1 values(2,'B'); 
已建立 1 行。
SQL> insert into merge_test1 values(3,'C'); 
已建立 1 行。
SQL> insert into merge_test2 values(3,'C'); 
已建立 1 行。
SQL> insert into merge_test2 values(2,'C'); 
已建立 1 行。
SQL> commit; 
提交完成。
SQL> select * from merge_test1; 
         A B
---------- --------------------
         1 A
         2 B
         3 C 
SQL> select * from merge_test2; 
         A B
---------- --------------------
         3 C
         2 C
前面的準備工作之後,用Merge對 Merge_test2進行更新
MERGE INTO MERGE_TEST2 M
USING MERGE_TEST1 N
ON (M.A = N.A)
WHEN MATCHED THEN
 UPDATE SET M.B = N.B
WHEN NOT MATCHED THEN
 INSERT (M.A,M.B) 
 VALUES (N.A,N.B); 
更新後結果:
SQL> select * from merge_test2; 
         A B
---------- --------------------
         1 A
         3 C 
         2 B 
總結:
一、Merge 的用法大致上有三種: 
1、只更新不插入
Merge into Merge_test2 M 
Using Merge_test1 N 
ON (M.A = N.A) 
WHEN MATCHED THEN 
UPDATE SET M.B = N.B; 
2、只插入不更新
MERGE INTO merge_test2 M 
USING merge_test1 N 
ON (M.A =N.A)  
WHEN NOT MATCHED THEN 
INSERT (M.A,M.B) VALUES(N.A,N.B); 
3、既插入也更新
MERGE INTO merge_test2 M 
USING merge_test1 N 
ON(M.A = N.A) 
WHEN  MATCHED THEN 
UPDATE SET M.B=N.B 
WHEN NOT MATCHED THEN 
INSERT (M.A,M.B)
 VALUES(N.A,N.B) 
二、注意事項
1、merge語句中,update不能用於更新連線的列(即ON(M.A = N.A)) 
例如:
MERGE INTO merge_test2 M 
USING merge_test1 N 
ON(M.A = N.A) 
WHEN  MATCHED THEN 
UPDATE SET M.A=N.B ,M.B=N.B 
WHEN NOT MATCHED THEN 
INSERT (M.A,M.B) VALUES(N.A,N.B) 
我們執行上面的語句(注意紅色部分)就會有如下的提示:
第 3 行出現錯誤:
ORA-38104: 無法更新 ON 子句中引用的列: "M"."A" ,不能更新on條件裡面的欄位M.A。因為M.A是2個表的連線條件。
2、Using 後面不一定是表:
語法文件上寫著:table,view,subquery 
也就是說也可以是一個查詢語句的結果集。
3、還有一種錯誤就是由於關聯的值不唯一引起的
比如:
在merge_test1中再插入一條資料。與之前的重複了!
SQL> insert into merge_test1 values(3,'d'); 
此時我們執行
MERGE INTO merge_test2 M 
USING merge_test1 N 
ON(M.A = N.A) 
WHEN  MATCHED THEN 
UPDATE SET M.B=N.B 
WHEN NOT MATCHED THEN 
INSERT (M.A,M.B) VALUES(N.A,N.B) 
第 1 行出現錯誤:
ORA-30926: 無法在源表中獲得一組穩定的行。原表不能有重複的值,否則報錯。




在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 結束事務。 


Merge是一個非常強大的功能,而且是我們需求裡經常會用到的一個有用的功能,所以我們一定要好好的學習到。

相關推薦

merge into 語句代替Insert/Update

不存在 BE 有時 改變 一個數 int 添加 數據 not merge into的形式: MERGE INTO [target-table] A USING [source-table sql] B ON([conditional expression] and [

oracle中按日期查詢報錯問題和merge into語句

1 ORA-01858 :在要求輸入數字處找到非數字字元 這兩個一起記述的主要原因是需要這樣做,且報錯了。。。 我先貼出我的sql語句來: 出錯原因是:preparedstatement在執行的時候不能把紅框內的串替換為sql中的問號,主要是to_date函式替換不了,解

Oracle之儲存過程和MERGE INTO語句

一、MERGE INTO語句   1、merge into語句的功能:我們操作資料庫的時候,有時候會遇到insert或者Update這種需求。我們操縱程式碼時至少需要寫一個插入語句和更新語句並且還得單獨寫方法效驗資料是否存在,這種操作完全可以用merge into語句代替,不僅省時省力而且條理更清晰,一個S

merge into 語句使用者

 merge into 語句 MERGE INTO [target-table] A USING [source-table sql] B ON([conditional expression] and [...]...) WHEN MATCHED THEN [UPDATE sq

oracle MERGE INTO語句使用方法(有則更新無則插入)

MERGE INTO T_APP_TJWT T1   --要插入或更新的表即要判斷的表 USING (SELECT '1001' AS a,'1111' AS b,'3333' as C FROM dual) T2  --判斷資料的表 ON ( T1.WTID=T2.a A

Merge into語句的使用

Merge into 用來從一個表中選擇一些資料更新或者插入到另一個表中。而最終是用更新還是用插入的方式取決於該語句中的條件。 如果N條記錄條件符合,就向目標表merge_test1 更新N條記錄。如果有M條記錄不符合要求,就向目標表merge_test1 插入M條記錄。

Db2 之 Merge Into語句詳解

在做資料備份的時候,我們通常情況下是建立一個同樣結構的表,定期將資料從生產表中寫入備份表中, 在備份間隔期間,生產資料會增加,會被修改,那麼有一種備份方法就是增量備份。 增量備份,就是每次只是備份自上次備份之後修改的資料。 備份資料,通常使用DB2特有的工具

DB2 Merge Into語句的使用

在做資料備份的時候,我們通常情況下是建立一個同樣結構的表,定期將資料從生產表中寫入備份表中, 在備份間隔期間,生產資料會增加,會被修改,那麼有一種備份方法就是增量備份。 增量備份,就是每次只是備份自上次備份之後修改的資料。 備份資料,通常使用DB2特有的工具去實現; 有一個

Merge Into 語句代替Insert/Update在Oracle中的應用實戰

動機: 想在Oracle中用一條SQL語句直接進行Insert/Update的操作。 說明: 在進行SQL語句編寫時,我們經常會遇到大量的同時進行Insert/Update的語句 ,也就是說當存在記錄時,就更新(Update),不存在資料時,就插入(Insert)。 實戰:

Oracle merge into的用法,以及MySQL的相同功能語句

今天在重構以前的程式碼發現一個效率比較低的SQL,插入一條資料的時候先查詢,如果不為空,則進行更新操作,如果為空則插入,則插入。 一,Oracle merge into emp a using (select '111' as id,'周文軍' as name from d

MERGE INTO 解決大數據量 10w 更新緩慢的問題

update div and ble 更新數據 提高 關聯 type 條件 有個同事處理更新數據緩慢的問題,數據量超10w的量,更新速度太慢耗時較長,然後改成了 MERGE INTO 效率顯著提高。 使用方法如下 MERGE INTO 表A USING 表B ON 關聯

Oracle中Merge into用法總結 (轉載)

字符 存在 sin 刪除 ron mic 但是 多個 前段時間 Oracle中Merge into用法總結 (出處:http://www.cnblogs.com/dongsheng/p/4384754.html) 起因:   前段時間,因為涉及到一張表的大數據操作,要同時

SQL Server中的Merge Into

通過 例如 庫存 com borde del 進行 基礎上 date 簡介 Merge關鍵字是一個神奇的DML關鍵字。它在SQL Server 2008被引入,它能將Insert,Update,Delete簡單的並為一句。MSDN對於Merge的解釋非常的短小精悍:

merge into

align lec syntax pda ima int indicator images lin MERGE INTO T T1USING (SELECT a,b FROM T WHERE t.a=‘1001‘) T2ON ( T1.a=T2.a)WHEN MATCHED

oracle中 merge into 的用法

大數據 char 條件 http -1 alt mat 一個表 dml語句 很多時候我們需要通過篩選條件同時對表進行 更新,插入,刪除 等操作。這樣如果我們單一的去操作表會顯得很麻煩,下面會說到這個merge into 的用法會極大的優化我們操作表的時間和代碼量。 舉例,

oracle中merge into的使用

rollback 裏的 get express pre sql語句 可選 需求 目標 Oracle在9i引入了merge命令, 通過這個merge你能夠在一個SQL語句中對一個表同時執行inserts和updates操作. 當然是update還是insert是依據於你的指定

使用mysql merge into 時遇到的mysql #1093錯誤的解決

不存在 book 遇到 就是 圖片 查詢條件 event ide 分享 2018年2月11日15:34:23 做PHP開發時,要寫一個SQL語句。就是如果表中存在相應的記錄時,就執行更新,不存在就執行插入。 記得以前做SQL SERVER時,有merge into 語句

翻譯:replace into語句(已提交到MariaDB官方手冊)

microsoft pan ont 網站 log https nbsp 系列 www. 本文為mariadb官方手冊:REPLACE INTO的譯文。 原文:https://mariadb.com/kb/en/replace/ 我提交到MariaDB官方手冊的譯文:h

Insert Into 語句的語法錯誤

img ins height display 數據 play 技術 wid info 錯誤示意: 一開始程序是: 改正: 一條很簡單的插入語句竟然會報錯,然而直接在數據庫的查詢中執行中卻沒有問題,這個問題困擾了不少時間。 數據庫使用的是ACCESS,INSERT IN

oracle數據庫,覆蓋插入數據---- merge into

sel using update 需要 數據 裏的 oracle 插入數據 keyword 在開發中我們經常會碰到這麽一個場景,列如用戶修改簡單的個人基本信息,這個時候就需要判斷用戶的基本信息是否存在,如果是首次錄入不存在就在表中插入一條信息,如果存在就更新表裏的信息。