Merger into是oracle從9i開(kāi)始增加的一個(gè)語(yǔ)句,從merge的字面上的意思:合并,兼并不難理解merge在oracle中的含義,merge在oracle所起的作用是:如果你從以組值中有選擇的更新和插入到到一張表,具體來(lái)說(shuō)是:如果該表中已經(jīng)匹配了這組值的某些條件,那么可以使用這組值的部分?jǐn)?shù)據(jù)來(lái)更新這個(gè)表的,如果該表中無(wú)法匹配了這組值的某些條件,那么可以使用這組值的數(shù)據(jù)來(lái)為這個(gè)表新增一條數(shù)據(jù)。
無(wú)論你在使用任何DBMS,你總是難以避免的將會(huì)遇到上面提到的這種需求,如果你不使用merge語(yǔ)句,你將會(huì)不得不在程序中增加大段的代碼,或者是在oracle用很長(zhǎng)的代碼來(lái)實(shí)現(xiàn)。好在現(xiàn)在我們有了merge,可以幫我們省下很多時(shí)間。
好了廢話少說(shuō):
Merge 的基本語(yǔ)法是這樣的
Merge into table[alias]
Using table or sql query [alias]
On condition
When matched then
Update set ….
When not matched then
Insert values…
以上是merge的基本語(yǔ)法,其中
alias是為表或者查詢寫(xiě)的別名
如果你看著空洞的語(yǔ)法覺(jué)得頭很痛,看下面的例子吧
首先我們創(chuàng)建兩個(gè)表
create table test1(id int,name varchar(20));
create table test2(id int,name varchar(20))
然后隨意插入幾行數(shù)據(jù)
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中的數(shù)據(jù)有選擇地轉(zhuǎn)移或者更新到test1中
如果你運(yùn)行了下下面的merge語(yǔ)句,你將會(huì)的到一個(gè)錯(cuò)誤,這是因?yàn)閛racle規(guī)定在merge語(yǔ)句中不能更新作為連接的列,也就是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);
所以將會(huì)得到如下的錯(cuò)誤,雖然這個(gè)錯(cuò)誤翻譯的并不怎么樣,甚至帶有明顯的誤導(dǎo)
on (t1.id = t2.id)
*
ERROR 位于第 3 行:
ORA-00904: “T1″.”ID”: 無(wú)效的標(biāo)識(shí)符
好了,知錯(cuò)就改,我們?cè)賮?lái)運(yùn)行下面的merge語(yǔ)句。
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)
成功執(zhí)行了,我們來(lái)驗(yàn)證一下。
select * from test1;

ID NAME
—— —————-
1 hi
2 你好
3 morning
至此,你已經(jīng)掌握了merge語(yǔ)句中的大部分。但我們還要提醒一些特殊情況。
如果我們?cè)傧騮est2中增加一條語(yǔ)句
insert into test2 values(2,’早’)
再執(zhí)行我們以已經(jīng)成功執(zhí)行過(guò)的merge語(yǔ)句,將會(huì)遇到下面的錯(cuò)誤
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: 無(wú)法在源表中獲得一組穩(wěn)定的行
這是因?yàn)楫?dāng)執(zhí)行到t1.id = t2.id =2時(shí),test2表中對(duì)應(yīng)了兩條記錄,無(wú)法進(jìn)行更新或者插入。所以就出錯(cuò)了。所以你應(yīng)該明白o(hù)racle中的merge語(yǔ)句應(yīng)該保證on中的條件的唯一性,
另外一點(diǎn)需要說(shuō)明的是using關(guān)鍵字后面可以接表,當(dāng)然也可以接其他的select語(yǔ)句做出來(lái)的一個(gè)類視圖,oracle中的這種結(jié)構(gòu),我們?cè)谇懊嬉呀?jīng)介紹多次,在此不作介紹。