`

Merge Into 语句代替Insert/Update在Oracle中的应用实战

 
阅读更多

动机:

想在Oracle中用一条SQL语句直接进行Insert/Update的操作。

说明:

在进行SQL语句编写时,我们经常会遇到大量的同时进行Insert/Update的语句 ,也就是说当存在记录时,就更新(Update),不存在数据时,就插入(Insert)。

实战:

接下来我们有一个任务,有一个表T,有两个字段a,b,我们想在表T中做Insert/Update,如果存在,则更新T中b的值,如果不存在,则插入一条记录。在Microsoft的SQL语法中,很简单的一句判断就可以了,SQL Server中的语法如下:

if exists(select 1 from T where T.a='1001' ) update T set T.b=2 Where T.a='1001' else insert into T(a,b) values('1001',2);

以上语句表明当T表中如果存在a='1001' 的记录的话,就把b的值设为2,否则就Insert一条a='100',b=2的记录到T中。

但是接下来在Oracle中就遇到麻烦了,记得在Oracle 9i之后就有一条Merge into 的语句可以同时进行Insert 和Update的吗,Merge的语法如下:

MERGE INTO table_name alias1 
USING (
table|view|sub_query) alias2
ON (join condition) 
WHEN MATCHED THEN 
    
UPDATE table_name 
    
SET col1 = col_val1, 
        col2     
= col2_val 
WHEN NOT MATCHED THEN 
    
INSERT (column_list) VALUES (column_values); 

 

上面的语法大家应该都容易懂吧,那我们按照以上的逻辑再写一次。

MERGE INTO T T1
USING (
SELECT a,b FROM T WHERE t.a='1001') T2
ON ( T1.a=T2.a)
WHEN MATCHED THEN
  
UPDATE SET T1.b = 2
WHEN NOT MATCHED THEN 
  
INSERT (a,b) VALUES('1001',2);

以上的语句貌似很对是吧,实际上,该语句只能进行更新,而无法进行Insert,错误在哪里呢?

其实在Oracle中Merge语句原先是用来进行整表的更新用的,也就是ETL工具比较常用的语法,重点是在Using上。

用中文来解释Merge语法,就是:

在alias2中Select出来的数据,每一条都跟alias1进行 ON (join condition)的比较,如果匹配,就进行更新的操作(Update),如果不匹配,就进行插入操作(Insert)。

因此,严格意义上讲,”在一个同时存在Insert和Update语法的Merge语句中,总共Insert/Update的记录数,就是Using语句中alias2的记录数。”

以上这句话也就很好的解释了在上面写的语句为何只能进行Update,而不能进行Insert了,因为都Select不到数据,如何能进行Insert呢:)

接下来要改成正确的语句就容易多了,如下:

MERGE INTO T T1
USING (
SELECT '1001' AS a,2 AS b FROM dual) T2
ON ( T1.a=T2.a)
WHEN MATCHED THEN
  
UPDATE SET T1.b = T2.b
WHEN NOT MATCHED THEN 
  
INSERT (a,b) VALUES(T2.a,T2.b);

查询结果,OK!

注意:

如果不懂Merge语句的原理,Merge语句是一条比较危险的语句,特别是在您只想更新一条记录的时候,因为不经意间,你可能就把整表的数据都Update了一遍.....汗!!!

我曾经犯过的一个错误如下所示,大家看出来是什么问题了吗?

MERGE INTO T T1
USING (
SELECT Count(*) cnt FROM T WHERE T.a='1001') T2
ON (T2.cnt>0)
WHEN MATCHED THEN
  
UPDATE SET T1.b = T2.b
WHEN NOT MATCHED THEN 
  
INSERT (a,b) VALUES(T2.a,T2.b);

  <!-- Baidu Button BEGIN -->

 

 

分享到:
评论

相关推荐

    Merge Into 语句代替InsertUpdate

    非常经典的SQL经验,适合于数据库初学者及长期从事软件开发者

    Oracle中merge into的使用

    Oracle中merge into的使用 很有用的哦 学习一下

    Oracle merge into用法

    关于Oracle中merge into的用法,比较实用哦

    oracle merge into的使用

    oracle merge into的使用,开发必备的。

    DB2 MERGE INTO语句的使用

    DB2中的Merge语句可以将一个表中的数据合并到另一个表中,在合并的同时可以根据条件进行插入、删除、更新等操作,功能非常强大。

    update语句的优化-oracle .pdf

    实际项目中遇到的问题总结:数据量百万级,千万级。Oracle中update语句的优化,一共四种方案,工作中遇到该类问题可以参考。

    浅谈Oracle数据库中Merge Into的用法.pdf

    浅谈Oracle数据库中Merge Into的用法.pdf

    Mybatis批量foreach merge into的用法

    Mybatis批量foreach merge into的用法,这是介绍Mybatis批量foreach merge into的用法的文档

    Merge into的使用详解

    Merge into写法,含两种,带实例说明

    使用BULK COLLECT, MERGE 语句提高sql执行效率

    详细介绍了使用 BULK COLLECT 进行批量操作 提高sql的执行效率 使用MERGE INTO USING 一条sql搞定 新增和修改 使用connect by 进行递归树查询

    MySQL中实现插入或更新操作(类似Oracle的merge语句)

    如果需要在MySQL中实现记录不存在则insert,不存在则update操作。可以使用以下语句: 更新一个字段: INSERT INTO tbl (columnA,columnB,columnC) VALUES (1,2,3) ON DUPLICATE KEY UPDATE columnA=IF(columnB&gt;0,...

    Oracle merge合并更新函数实例详解

    通过这个MERGE你能够在一个SQL语句中对一个表同时执行INSERT和UPDATE操作. 本博客介绍一下Oracle merge合并函数,业务场景:新增数据的时候要先查询数据库是否已经有改数据,有数据就更新数据,没数据才新增数据,这...

    oracle中merge into用法及实例解析

    merge into的形式: MERGE INTO [target-table] A USING [source-table sql] B ON([conditional expression] and [...]...) WHEN MATCHED THEN [UPDATE sql] WHEN NOT MATCHED THEN [INSERT sql] 作用:判断B表...

    oracle死锁原因解决办法

    在任何数据库中发生死锁都是不愉快的,即使是在一个特殊的情况下发生也是如此,它们会减小应用程序的接受程度(ACCEPTANCE),因此避免并正确解释死锁是非常重要的。

    Oracle_merge

    在Oracle 9i R2版中引入的MERGE语句通常被称作“更新插入”(upsert),因为使用MERGE可以在同一个步骤中更新(update)并插入(insert)数据行。。。。。。

    精通Oracle 10g SQL和PL/SQL

     本书是专门为oracle开发人员而提供的编程指南 通过学习本书 读者不仅可以掌握编写sql语句和pl/sql块的基础知识 而且还可以掌握sql高级特征 正则表达式 flashback查询 merge语句 sql:1999连接 和pl/sql高级特征 ...

    Oracle MERGE INTO的用法示例介绍

    1)主要功能 提供有条件地更新和插入数据到数据库表中 如果该行存在,执行一个UPDATE操作,如果是一个新行,执行INSERT操作 — 避免了分开更新 — 提高性能并易于使用 — 在数据仓库应用中十分有用 2)MERGE语句的...

    SDLXLIFF file Split and Merge

    Free software for agile handling of Trados Studio tasks.

Global site tag (gtag.js) - Google Analytics