Oracle Merge 使用
来源:互联网 发布:怎么在淘宝上赚钱 编辑:程序博客网 时间:2024/05/18 09:21
Oracle9i引入了MERGE命令,你能够在一个SQL语句中对一个表同时执行inserts和updates操作. MERGE命令从一个或多个数据源中选择行来updating或inserting到一个或多个表.在Oracle10g中MERGE有如下一些改进:
1、UPDATE或INSERT子句是可选的
2、UPDATE和INSERT子句可以加WHERE子句
3、在ON条件中使用常量过滤谓词来insert所有的行到目标表中,不需要连接源表和目标表
4、UPDATE子句后面可以跟DELETE子句来去除一些不需要的行
语法:
MERGEHINTINTOSCHEMA .TABLE T_ALIAS
USINGSCHEMA . {TABLE |VIEW |SUBQUERY } T_ALIAS
ON (CONDITION)
WHENMATCHEDTHEN MERGE_UPDATE_CLAUSE
WHENNOTMATCHEDTHEN MERGE_INSERT_CLAUSE / MERGE_DELETE_CLAUSE;
联想:
merge into是特有的功能,相当于在 MSSQL中的
ifexists(...)
updatetable
else
Insertinto table.
mergeinto语法不仅没有if exists语法啰嗦,而且比if exists还要高效很多,常用来在oracle之间同步数据库表。
例子:
1、创建测试表及数据
- DROP TABLE PRODUCTS;
- DROP TABLE NEWPRODUCTS;
- create table PRODUCTS
- (
- PRODUCT_ID INTEGER,
- PRODUCT_NAME VARCHAR2(60),
- CATEGORY VARCHAR2(60)
- );
- insert into PRODUCTS values (1501, 'VIVITAR 35MM', 'ELECTRNCS');
- insert into PRODUCTS values (1502, 'OLYMPUS IS50', 'ELECTRNCS');
- insert into PRODUCTS values (1600, 'PLAY GYM', 'TOYS');
- insert into PRODUCTS values (1601, 'LAMAZE', 'TOYS');
- insert into PRODUCTS values (1666, 'HARRY POTTER', 'DVD');
- commit;
- create table NEWPRODUCTS
- (
- PRODUCT_ID INTEGER,
- PRODUCT_NAME VARCHAR2(60),
- CATEGORY VARCHAR2(60)
- );
- insert into NEWPRODUCTS values (1502, 'OLYMPUS CAMERA', 'ELECTRNCS');
- insert into NEWPRODUCTS values (1601, 'LAMAZE', 'TOYS');
- insert into NEWPRODUCTS values (1666, 'HARRY POTTER', 'TOYS');
- insert into NEWPRODUCTS values (1700, 'WAIT INTERFACE', 'BOOKS');
- commit;
2、匹配更新
- 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,
- P.CATEGORY = NP.CATEGORY;
- SELECT * FROM PRODUCTS;
- SELECT * FROM NEWPRODUCTS;
3、不匹配插入
- MERGE INTO PRODUCTS P
- USING NEWPRODUCTS NP
- ON (P.PRODUCT_ID = NP.PRODUCT_ID)
- WHEN NOT MATCHED THEN
- INSERT
- (PRODUCT_ID
- ,PRODUCT_NAME
- ,CATEGORY)
- VALUES
- (NP.PRODUCT_ID
- ,NP.PRODUCT_NAME
- ,NP.CATEGORY);
- SELECT * FROM PRODUCTS;
- SELECT * FROM NEWPRODUCTS;
4、匹配带where/on更新
- 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 WHERE P.CATEGORY = NP.CATEGORY;
- MERGE INTO PRODUCTS P
- USING NEWPRODUCTS NP
- ON (P.PRODUCT_ID = NP.PRODUCT_ID AND P.CATEGORY = NP.CATEGORY)
- WHEN MATCHED THEN
- UPDATE SET P.PRODUCT_NAME = NP.PRODUCT_NAME;
- SELECT * FROM PRODUCTS;
- SELECT * FROM NEWPRODUCTS;
- SELECT *
- FROM PRODUCTS A
- INNER JOIN NEWPRODUCTS B
- ON A.PRODUCT_ID = B.PRODUCT_ID
- AND A.CATEGORY = B.CATEGORY;
5、匹配带where更新、插入
- 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,
- P.CATEGORY = NP.CATEGORY
- WHERE P.CATEGORY = 'DVD'
- WHEN NOT MATCHED THEN
- INSERT
- (PRODUCT_ID
- ,PRODUCT_NAME
- ,CATEGORY)
- VALUES
- (NP.PRODUCT_ID
- ,NP.PRODUCT_NAME
- ,NP.CATEGORY) WHERE NP.CATEGORY != 'BOOKS';
- SELECT * FROM PRODUCTS;
- SELECT * FROM NEWPRODUCTS;
6、ON常量表达式
- MERGE INTO PRODUCTS P
- USING NEWPRODUCTS NP
- ON (1 = 0)
- WHEN NOT MATCHED THEN
- INSERT
- (PRODUCT_ID
- ,PRODUCT_NAME
- ,CATEGORY)
- VALUES
- (NP.PRODUCT_ID
- ,NP.PRODUCT_NAME
- ,NP.CATEGORY) WHERE NP.CATEGORY = 'BOOKS';
- SELECT * FROM PRODUCTS;
- SELECT * FROM NEWPRODUCTS;
7、匹配删除、不匹配插入
- 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,
- P.CATEGORY = NP.CATEGORY DELETE
- WHERE (P.CATEGORY = 'ELECTRNCS')
- WHEN NOT MATCHED THEN
- INSERT
- (PRODUCT_ID
- ,PRODUCT_NAME
- ,CATEGORY)
- VALUES
- (NP.PRODUCT_ID
- ,NP.PRODUCT_NAME
- ,NP.CATEGORY);
- SELECT * FROM PRODUCTS;
- SELECT * FROM NEWPRODUCTS;
8、源表为子查询(自联接)
- MERGE INTO PRODUCTS P
- USING (SELECT COUNT(*) CO FROM PRODUCTS WHERE PRODUCTS.PRODUCT_ID = 1501) B
- ON (B.CO <> 0)
- WHEN MATCHED THEN
- UPDATE SET P.PRODUCT_NAME = 'KEBO' WHERE P.PRODUCT_ID = 1501
- WHEN NOT MATCHED THEN
- INSERT
- (PRODUCT_ID
- ,PRODUCT_NAME
- ,CATEGORY)
- VALUES
- (1501
- ,'KEBO'
- ,'NBA');
- MERGE INTO PRODUCTS P
- USING (SELECT COUNT(*) CO FROM PRODUCTS WHERE PRODUCTS.PRODUCT_ID = 1508) B
- ON (B.CO <> 0)
- WHEN MATCHED THEN
- UPDATE SET P.PRODUCT_NAME = 'KEBO' WHERE P.PRODUCT_ID = 1508
- WHEN NOT MATCHED THEN
- INSERT
- (PRODUCT_ID
- ,PRODUCT_NAME
- ,CATEGORY)
- VALUES
- (1508
- ,'KEBO'
- ,'NBA');
- SELECT * FROM PRODUCTS;
优点:
—避免了分开更新
—提高性能并易于使用
—在数据仓库应用中十分有用
—使用merge比传统的先判断再选择插入或更新快很多
需要注意的地方:
1、从语法条件上看(ON (join condition)),merge into也是一个危险的语法。如果不慎重使用,会将源表全部覆盖到目标表,既危险又浪费效率,违背了增量同步的原则。所以在设计表结构时,一般每条记录都有“更新时间”的字段,用目标表“最大更新时间”判断源表数据是否有更新和新增的信息。
2、更新的字段,不允许有关联条件的字段(join condition)。比如条件是 A.ID=B.ID,那么使用“SET A.ID=B.ID”将报出一个莫名其妙的提示错误。
缺少一个带delete语句选项的示例,暂为补上:
- 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, P.CATEGORY = NP.CATEGORY
- --WHERE (P.CATEGORY = 'ELECTRNCS')
- DELETE
- WHERE (P.CATEGORY = 'ELECTRNCS')
- WHEN NOT MATCHED THEN
- INSERT
- (PRODUCT_ID, PRODUCT_NAME, CATEGORY)
- VALUES
- (NP.PRODUCT_ID, NP.PRODUCT_NAME, NP.CATEGORY);
- SELECT * FROM PRODUCTS;
- SELECT * FROM NEWPRODUCTS;
说明:DELETE语句删除的是满足matched关联on条件,同时也要是update更新内容的子集,否则不会删除任何内容。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
http://blog.itpub.net/25313300/viewspace-700222/
1. MERGE INTO 的用途
MERGE INTO 是Oracle 9i以后才出现的新的功能。那这个功能 是什么呢?
简单来说,就是:“有则更新,无则插入”
从这句话里,应该可以理解到,merge into 操作一个对象'A'的时候,要有另外一个结果集做为源数据 'B'.
‘merge into’ 将B中的数据与A中的数据按照一定条件'C'进行对比,如果 A中数据满足C条件,则进行update操作,如果不满足条件 'C',则进行insert操作。(请注意这种对应关系)
2、 语法结构
MERGE [INTO] [schema.]table [alias]
USING {[schema.]table|views|query} [alias]
ON {condition}
WHEN MATCHED THEN UPDATE SET {clause}
WHEN NOT MATCHED THEN INSERT VALUES {clause}
我们可以用于单条数据的处理,也可以用于数据的批处理。对于merge into来说,那都是张飞吃豆芽儿,小菜一碟儿。而且效率要比单独执行update+insert 操作效率要高。
但是请注意,using语句中的结果集 B不可以与merge into 的对象A相同,否则,会因为结果集A,B恒等。
当 on() 进行等值判断时,只可以进行update操作,不能进行insert 操作,当 on() 进行不等值判断时,只可以进行insert操作,不能进行update操作。
可能这样说还不是很清楚。下面我们实际操作演示,就会理解清楚了。
3. 测试 MERGE INTO
--------------------------------------------------------------------------------------------------------------
------------------------------------- 创建测试表--TEST1 ----------------------------------
SQL> CREATE TABLE TEST1(
2 USERID NUMBER,
3 ID NUMBER);
Table created
--------------------------------------------------------------------------------------------------------------
---------------------------------- 填充测试数据 -------------------------------
SQL> begin
2 for i in 200..230 loop
3 insert into test1 values(i,(i+100)/10);
4 end loop;
5 end;
6 /
PL/SQL procedure successfully completed
SQL> select * from test1;
USERID ID
---------- ----------
200 30
201 30.1
202 30.2
203 30.3
204 30.4
205 30.5
206 30.6
207 30.7
208 30.8
209 30.9
210 31
211 31.1
212 31.2
213 31.3
214 31.4
215 31.5
216 31.6
217 31.7
218 31.8
219 31.9
USERID ID
---------- ----------
220 32
221 32.1
222 32.2
223 32.3
224 32.4
225 32.5
226 32.6
227 32.7
228 32.8
229 32.9
230 33
31 rows selected
--------------------------------------------------------------------------------------------------------------
----------------------------- 创建测试表--TEST2 、TEST3 --------------------------------
SQL> create table test2
2 as
3 select userid,trunc(id,-1) id2 from test1 where length(id)=4;
Table created
SQL> select * from test2;
USERID ID2
---------- ----------
201 30
202 30
203 30
204 30
205 30
206 30
207 30
208 30
209 30
211 30
212 30
213 30
214 30
215 30
216 30
217 30
218 30
219 30
221 30
222 30
USERID ID2
---------- ----------
223 30
224 30
225 30
226 30
227 30
228 30
229 30
27 rows selected
SQL> create table test3
2 as
3 select userid,id id3 from test1 where length(id) <> 4;
Table created
SQL> select * from test3;
USERID ID3
---------- ----------
200 30
210 31
220 32
230 33
--------------------------------------------------------------------------------------------------------------
----------------------------------- 测试MERGE INTO -----------------------------------
SQL> MERGE INTO test3 t
2 USING (SELECT userid,id2 FROM test2 WHERE id2=30) tw
3 ON (t.userid = tw.userid)
4 WHEN MATCHED THEN UPDATE SET t.id3=tw.id2
5 WHEN NOT MATCHED THEN INSERT VALUES(tw.userid,tw.id2);
Done
SQL> SELECT * FROM test3;
USERID ID3
---------- ----------
200 30
210 31
220 32
230 33
202 30
201 30
204 30
203 30
228 30
217 30
209 30
221 30
219 30
227 30
205 30
212 30
225 30
208 30
222 30
226 30
USERID ID3
---------- ----------
215 30
218 30
214 30
216 30
211 30
224 30
213 30
223 30
206 30
207 30
229 30
31 rows selected
SQL>
--测试完成,我们看到,test2表中的数据全部加到test3表中。
PS:
on(condition_clause)这里的条件句中,可以使用=,>,< 等比较运算符。
------------------------------------- The End -------------------------------------------
- Oracle Merge 使用
- Oracle Merge的使用
- Oracle Merge 使用
- Oracle Merge 语言使用
- Oracle Merge 使用
- oracle merge使用
- Oracle Merge 使用
- Oracle Merge 使用
- Oracle Merge 使用
- Oracle Merge 使用
- Oracle merge使用
- Oracle Merge 使用
- Oracle Merge 使用
- Oracle Merge 使用
- Oracle Merge 使用介绍
- Oracle Merge 使用
- oracle中的merge使用
- oracle中merge使用
- Servlet生命周期与工作原理
- hibernate使用总结(1)
- 5.19
- cmake编译QT5串口通信
- Requests: HTTP for Humans
- Oracle Merge 使用
- 53.Maximum Subarray&连续子数组的最大和
- java多线程编程
- CLLocationManager 定位不精确
- 二十个经典管理学定律
- Junit 单元测试
- 5.17
- __I、 __O 、__IO volatile是什么?怎么用? .
- 基于selenium生成Csdn 博客文章简索的excel文件