Oracle高階應用之合併MERGE

2021-06-19 06:39:02 字數 3736 閱讀 4895

為了方便大家學習和測試,所有的例子都是在oracle自帶使用者scott下建立的。

merge是什麼?這麼厲害的東西你都不知道,你這學生是怎麼學習的?老師不給你講你就不會自學了嗎?哎!可憐天下老師心啊,罷了罷了,老師現在給你好好講一下吧。

merge是oracle9i新增的語法,中文意思是「合併」,那合併什麼呢?它能合併insert和update在一條sql語句中執行,是不是很牛x?!還有更牛x的,就是在執行該條語句時只做一次全表掃瞄,效率非常高。是不是有點心癢難耐了,哈哈,不著急,老師接下來給你具體講講它的用法。不過在講之前我們需要做兩點準備工作:

一、建立測試表且填充測試資料

[sql]view plain

copy

create

table

merge_test 

asselect

* from

scott.dept  

二、修改測試表的資料,為了與原表scott.dept的資料產生差異。

[sql]view plain

copy

delete

from

merge_test t 

where

t.deptno=10  

[sql]view plain

copy

update

merge_test t 

sett.dname = 

'test'

ok,那現在客戶提出乙個需求,讓表merge_test中的機構資訊與scott.dept表保持一致。

這個太簡單了,執行下面的兩條sql語句不就可以了?!

[sql]view plain

copy

delete

from

merge_test  

[sql]view plain

copy

insert

into

merge_test 

select

* from

scott.dept  

不得不說這位同學確實有過人之處,這個別人想都不敢想的方法都被他想到了,老師只能說:「我要是你爸,當年你就在牆上了」。雖然說此方法確實到達了「目的」,但是卻太不完善了,如果客戶只想要保證機構名稱字段一致即可呢?此方法肯定便秘了,還有誰有更好的方法?

有!有!有!先把scott.dept表中的字段dname值更新到表merge_test的字段dname。

[sql]view plain

copy

update

merge_test m  

setdname =  

(select

dname 

from

scott.dept t 

where

m.deptno = t.deptno)  

再把沒在merge_test表中而在scott.dept表中的資料插入表merge_test。

[sql]view plain

copy

insert

into

merge_test m  

select

*  from

scott.dept  

where

deptno 

notin

(select

deptno 

from

merge_test)  

這位同學還不錯,有點sql基礎,很好,為了激勵其他同學能想出更好的方法,老師決定下課後給這位同學買小布丁吃。不過是否還有更好更便捷的方法呢?我想同學們的水平應該也就到這,那老師就不再謙虛了(老師是幹什麼使的?老師就是在你們不知道的時候讓你們知道,在你們都知道的時候回家睡大覺)。下面老師就給你們講一種更加高階的方法,先看sql語句。

[sql]view plain

copy

merge 

into

merge_test m using scott.dept t 

on(m.deptno = t.deptno) 

when

matched then

update

setm.dname = t.dname 

when

notmatched 

then

insert

values

(t.deptno, t.dname, t.loc)  

給同學解釋一下上面的語句,把錶scott.dept中的資料根據關聯條件m.deptno = t.deptno更新到merge_test表中,如果表merge_test中的deptno在表scott.dept中存在(matched 匹配),則執行更新操作update set m.dname = t.dname,如果表merge_test中的deptno在表scott.dept中不存在(not matched 不匹配),則執行插入操作insert values(t.deptno, t.dname, t.loc)。

一些聰明的同學可能會問了,只能全表操作嗎?可不可以根據篩選條件來操作呢?這樣的同學真讓人省心,你說老師能不喜歡嗎?!針對這個問題,答案是肯定的,比如我只想更新deptno=20的部門名稱,修改後的sql語句如下:

[sql]view plain

copy

merge 

into

merge_test m using scott.dept t 

on(m.deptno = t.deptno) 

when

matched then

update

setm.dname = t.dname  

where

(m.deptno = 20) 

when

notmatched 

then

insert

values

(t.deptno, t.dname, t.loc)  

為了表達老師是一位可愛的、正直的、無私的、(此處省略掉1500字褒義詞)人,老師決定在本節課最後贈送另外乙個「小禮品」給同學們。在該語法中甚至還可以使用delete,如果表merge_test中的deptno在表scott.dept中存在則刪除deptno=20的機構資訊,修改後的sql語句如下:

[sql]view plain

copy

merge 

into

merge_test m using scott.dept t 

on(m.deptno = t.deptno) 

when

matched then

update

setm.dname = t.dname 

delete

where

(m.deptno = 20) 

when

notmatched 

then

insert

values

(t.deptno, t.dname, t.loc)  

好了現在老師可以下課回家睡覺了,good good study, day day up.

備註:where與delete的語法是oracle10i新增的。

C巨集高階應用之

在巨集定義中經常看到 和 現在講一下他們的用法 1,是連線符 用於將兩個引數連線在一起 例如 define a x,y x y 則 a he llo 結果是hello define link a my a 則 link god 相當於 mygod 是一種分隔連線方式 他的作用是先分隔 然後強制連線 ...

oracle應用之sql小寫

本人不喜歡在sql裡面大小寫混合在一起,每次看到別人的sql,總是要轉換為小寫,如以下sql with t as select date 2014 05 06 time1,1 type,100 times from dual union all select date 2014 05 06 2,20...

C 高階應用之Microsoft Vsa引擎篇

引擎實現部分 using system using system.collections using system.io using system.reflection using microsoft.visualbasic.vsa using microsoft.vsa 作者注 需要增加對micr...