Merger into是oracle從9i開始增加的一個語句,從merge的字面上的意思:合并,兼并不難理解merge在oracle中的含義,merge在oracle所起的作用是:如果你從以組值中有選擇的更新和插入到到一張表,具體來說是:如果該表中已經匹配了這組值的某些條件,那么可以使用這組值的部分數據來更新這個表的,如果該表中無法匹配了這組值的某些條件,那么可以使用這組值的數據來為這個表新增一條數據。
無論你在使用任何DBMS,你總是難以避免的將會遇到上面提到的這種需求,如果你不使用merge語句,你將會不得不在程序中增加大段的代碼,或者是在oracle用很長的代碼來實現。好在現在我們有了merge,可以幫我們省下很多時間。
好了廢話少說:
Merge 的基本語法是這樣的
Merge into table[alias]
Using table or sql query [alias]
On condition
When matched then
Update set ….
When not matched then
Insert values…
以上是merge的基本語法,其中alias是為表或者查詢寫的別名
如果你看著空洞的語法覺得頭很痛,看下面的例子吧
首先我們創建兩個表
create table test1(id int,name varchar(20));
create table test2(id int,name varchar(20))
然后隨意插入幾行數據
insert into test1 values(1,’hi’);
insert into test1 values(2,’hello’);
insert into test2 values(2,’你好’);
insert into test2 values(3,’morning’);
下面我們要使用了merge了,將test2中的數據有選擇地轉移或者更新到test1中
如果你運行了下下面的merge語句,你將會的到一個錯誤,這是因為oracle規定在merge語句中不能更新作為連接的列,也就是on后面的那些列
merge into test1 t1
using test2 t2
on (t1.id = t2.id)
when matched then
update set t1.id = t2.id
when not matched then
insert values(t2.id,t2.name);
所以將會得到如下的錯誤,雖然這個錯誤翻譯的并不怎么樣,甚至帶有明顯的誤導
on (t1.id = t2.id)
*
ERROR 位于第 3 行:
ORA-00904: “T1″.”ID”: 無效的標識符
好了,知錯就改,我們再來運行下面的merge語句。
merge into test1 t1
using test2 t2
on (t1.id = t2.id)
when matched then
update set t1.name = t2.name
when not matched then
insert values(t2.id,t2.name)
成功執行了,我們來驗證一下。
select * from test1;
ID NAME
—— —————-
1 hi
2 你好
3 morning
至此,你已經掌握了merge語句中的大部分。但我們還要提醒一些特殊情況。
如果我們再向test2中增加一條語句
insert into test2 values(2,’早’)
再執行我們以已經成功執行過的merge語句,將會遇到下面的錯誤
SQL> merge into test1 t1
2 using test2 t2
3 on (t1.id = t2.id)
4 when matched then
5 update set t1.name = t2.name
6 when not matched then
7 insert values(t2.id,t2.name)
8 ;
using test2 t2
*
ERROR 位于第 2 行:
ORA-30926: 無法在源表中獲得一組穩定的行
這是因為當執行到t1.id = t2.id =2時,test2表中對應了兩條記錄,無法進行更新或者插入。所以就出錯了。所以你應該明白oracle中的merge語句應該保證on中的條件的唯一性,
另外一點需要說明的是using關鍵字后面可以接表,當然也可以接其他的select語句做出來的一個類視圖,oracle中的這種結構,我們在前面已經介紹多次,在此不作介紹。