Merge into使用詳解( 同時執行inserts和updates操作 )
Merge是一個非常有用的功能,類似於MySQL裡的insert into on duplicate key.
Oracle在9i引入了merge命令, 透過這個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 ]
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) 在這個例子裡。
前面的merger into products using newproducts 表示的用newproducts表來merge到products表,merge的匹配關係就是on後面的條件子句的內容,這裡根據兩個表的product_id來進行匹配,那麼匹配上了我們的操作是就是when matched then的子句裡的動作了,這裡的動作是update set p.product_name = np.product_name, 很顯然就是把newproduct裡的內容,賦值到product的product_name裡。如果沒有匹配上則insert這樣的一條語句進去。 大家看看這個merget inot的用法是不是一目瞭然了呀。這裡merger的功能,好比比較,然後選擇更新或者是插入,是一系列的組合拳,在做merge的時候,這樣同樣的情況下,merge的效能是優於同等功能的update/insert語句的。有人曾經分析merge是批次處理對效能貢獻很大,個人覺得這個是沒有考據的。 我們也可以在using後面使用檢視或者子查詢。比如我們把newproducts換成 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 when not matched then insert values(np.product_id, np.product_name, np.category) 也是可以的。
在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是一個非常強大的功能,而且是我們需求裡經常會用到的一個有用的功能,所以我們一定要好好的學習到。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31383567/viewspace-2136552/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java 執行時(RUNTIME)註解詳解Java
- iis和tomcat同時執行,完美解決80埠衝突問題Tomcat
- 詳解Map.merge()
- Linux下使用timedatectl命令時間時區操作詳解Linux
- JVM詳解(三)——執行時資料區JVM
- JAVA多執行緒詳解(3)執行緒同步和鎖Java執行緒
- 同時使用gpcrondump和gpbackup
- JVM詳解(四)——執行時資料區-堆JVM
- 多執行緒系列(二十) -CompletableFuture使用詳解執行緒
- 多執行緒系列(十九) -Future使用詳解執行緒
- Python程式和執行緒例項詳解Python執行緒
- IDEA如何同時執行兩個ModulesIdea
- PHP 使用檔案鎖 避免同時執行一個指令碼PHP指令碼
- java--執行緒池--建立執行緒池的幾種方式與執行緒池操作詳解Java執行緒
- 什麼?一個核同時執行兩個執行緒?執行緒
- 多執行緒詳解執行緒
- 詳解多執行緒執行緒
- PHP 執行方式詳解PHP
- PHP 避免同時執行一個指令碼PHP指令碼
- springBoot @Scheduled多工同時開始執行Spring Boot
- 同時使用mybatis和mybatis-plus時,pageHelper失效問題解決MyBatis
- 詳解執行緒池的作用及Java中如何使用執行緒池執行緒Java
- git分支管理--rebase&merge詳解Git
- Linux下的crontab定時執行任務命令詳解Linux
- Java 虛擬機器執行時資料區詳解Java虛擬機
- Centos 7下利用crontab定時執行任務詳解CentOS
- 教你如何同時執行經典版和Chromium版Edge瀏覽器瀏覽器
- 多執行緒系列(二十一) -ForkJoin使用詳解執行緒
- Git - 使用命令和P4Merge進行diffGit
- 避免DbContext同時在多個執行緒呼叫Context執行緒
- 詳解Java執行緒安全Java執行緒
- iOS 多執行緒詳解iOS執行緒
- iOS執行器performSelector詳解iOSperformSelector
- js執行機制詳解JS
- Java執行緒池詳解Java執行緒
- Explain執行計劃詳解AI
- Java多執行緒詳解Java執行緒
- Java 執行緒池詳解Java執行緒
- 當同時安裝Python2和Python3後,如何相容並切換使用詳解(比如pip使用)Python