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

前言

MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句。 通过MERGE语句,根据一张表或多表联合查询的连接条件对另外一张表进行查询,连接条件匹配上的进行UPDATE,无法匹配的执行INSERT。这个语法仅需要一次全表扫描就完成了全部工作,执行效率要高于INSERT+UPDATE。通过这个MERGE你能够在一个SQL语句中对一个表同时执行INSERT和UPDATE操作.

本博客介绍一下Oracle merge合并函数,业务场景:新增数据的时候要先查询数据库是否已经有改数据,有数据就更新数据,没数据才新增数据,这是很常见的业务场景,如果是用Oracle数据库的话,其实直接用merge函数效率更快,而且merge函数性能也相对比较好

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 = col_val2
WHEN NOT MATCHED THEN
 INSERT (column_list) VALUES (column_values); 

举个例子:

SQL实现,意思是有数据就更新,没数据才新增

MERGE INTO t_config_related A1 USING(select '97547758-6f85-419e-85f9-b8f711ca2660' seq,
   '97547758-6f85-419e-85f9-b8f711ca2658' tipsSeq,
   to_number('1') appLevel,
   '24e1ccc38d9542189d1cc6c23f814a18' relaSeq from dual) A2
ON(A1.seq = A2.seq)
WHEN MATCHED THEN
UPDATE SET
  A1.tips_seq = A2.tipsSeq,
  A1.app_level = A2.appLevel,
  A1.rela_seq = A2.relaSeq
WHEN NOT MATCHED THEN
INSERT(seq , tips_seq , app_level , rela_seq)
VALUES(A2.seq , A2.tipsSeq , A2.appLevel , A2.relaSeq);
/**
  * 批量更新保存地区关联信息
  * @date 2019年2月21日上午11:17:10
  * @return
  */

 @RequestMapping("/batchSaveTipsAreaConfig")
 @ResponseBody
 public ResultModel batchSaveTipsConfig(ApprTipsRelatedModel relatedModel) {

  List<ApprTipsRelatedModel> areaTipsList = new ArrayList<ApprTipsRelatedModel>();

  //封装批量更新的地区列表

  String[] areaSeqs = StringUtils.split(relatedModel.getAreaSeq(),",");

  for (String areaSeq : areaSeqs) {

   ApprTipsRelatedModel areaRelatedModelNew = new ApprTipsRelatedModel();

   areaRelatedModelNew.setSeq(commonService.generateUUID());

   areaRelatedModelNew.setTipsSeq(relatedModel.getTipsSeq());

   areaRelatedModelNew.setAppLevel(NumConstant.COMMON_NUM_TREE);

   areaRelatedModelNew.setRelaSeq(areaSeq);

   areaTipsList.add(areaRelatedModelNew);

 }

  //批量更新新增数据

  try {

   this.tipsConfigService.batchSaveTipsRelatedConfig(areaTipsList);

   return ResultModel.success("保存成功");

  } catch(Exception e) {

   logger.error("批量绑定地区异常:{}"+e);

   throw new SuperControllerException();

  }

 }

注意要点:

在开发中我遇到一个异常,mybatis打印出来的SQL是这样的:

Preparing: MERGE INTO appr_tips_config_related A1 ? USING( ? ? ? ? ? select ? seq , ? tipsSeq , ? appLevel , ? relaSeq from dual ? ? ? ? ) A2 ? ON( ? ? ? ? ?A1.seq = A2.seq ? ? ?) ? WHEN MATCHED THEN ? ? UPDATE SET A1.seq = A2.seq, A1.tips_seq = A2.tipsSeq, A1.app_level = A2.appLevel, A1.rela_seq = A2.relaSeq ? ? ?WHEN NOT MATCHED THEN ? ? ?INSERT(seq,tip_seq,app_level,rela_seq) ? ? ? ? VALUES(A2.seq , A2.tipsSeq , A2.appLevel , A2.relaSeq) 

可以看出什么问题?打印出的SQL有很多问号,那是因为SQL有空格导致的,所以使用merge函数不用随便加空格,不然会报错的

? USING( ? ? ? ? ? select ? seq , ? tipsSeq , ? appLevel , ? relaSeq from dual ? ? ? ? ) A2 ? ON( ? ? ? ? ?A1.seq = A2.seq ? ? ?) ? 

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Oracle中sql语句(+)符号代表连接的使用讲解

    oracle中sql语句(+)符号代表连接 (+)在=前边为右连接 (+)在=后边为左连接 SELECT a.*, b.* from a(+) = b就是一个右连接,等同于select a.*, b.* from a right join b SELECT a.*, b.* from a = b(+)就是一个左连接,等同于select a.*, b.* from a left join b 内连接 常用的连接运算符=.<.> 使用比较运算符根据每个表共有的列的值匹配两个表中的行 外连接 左连接

  • MySQL实现类似Oracle序列的方案

    MySQL实现类似Oracle的序列 Oracle一般使用序列(Sequence)来处理主键字段,而MySQL则提供了自增长(increment)来实现类似的目的: 但在实际使用过程中发现,MySQL的自增长有诸多的弊端:不能控制步长.开始索引.是否循环等:若需要迁移数据库,则对于主键这块,也是个头大的问题. 本文记录了一个模拟Oracle序列的方案,重点是想法,代码其次. Oracle序列的使用,无非是使用.nextval和.currval伪列,基本想法是: 1.MySQL中新建表,用于存储序

  • SELECT INTO 和 INSERT INTO SELECT 两种表复制语句详解(SQL数据库和Oracle数据库的区别)

    1.INSERT INTO SELECT语句 语句形式为:Insert into Table2(field1,field2,...) select value1,value2,... from Table1 或者:Insert into Table2 select * from Table1 注意:(1)要求目标表Table2必须存在,并且字段field,field2...也必须存在 (2)注意Table2的主键约束,如果Table2有主键而且不为空,则 field1, field2...中必须

  • 如何利用Oracle命令解决函数运行错误

    1 问题 自定义了一个 Oracle 函数.编译正常:使用 PL/SQL Developer 的 Test 窗口模式,测试通过.但 Java 直接调用失败:使用 PL/SQL Developer 的 SQL 窗口模式,执行失败. 没有有效的错误提示信息. 2 分析 肯定是函数本身有问题,我们要使用有效的工具来定位出问题. 在 Oracle 函数中,加入异常处理. 异常处理 (EXCEPTION)  可用来处理正常执行过程中未预料的事件.如果 PL/SQL 程序块产生异常,但没有指定如何处理时 ,

  • 为Plesk PHP7启用Oracle OCI8扩展方法总结

    注:本文适用于RHEL/CentOS发行版. 步骤1.安装构建自定义PHP 7模块所需的devel包 # yum install plesk-php70-devel gcc glibc-devel libmemcached-devel zlib-devel make libaio.x86_64 步骤2.下载oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm和oracle-instantclient12.1-devel-12.1.0.2.0

  • oracle如何解锁封锁的账号

    (1)我们在安装Oracle的时候最后一步有一个管理账户的,里边可以解锁所所需的账户,但是很多的人有时候没有解锁, 下边研究一下使用命令行的方式解锁账户 (2)启动SQL Plus 先登录SYSTEM账户(密码是你自己安装的时候创建的) 然后连接成功之后输入:alter user scott account unlock; (3)这时候一看到scott账户已成功解锁 (4)登陆一下试试 好的  连接成功! 总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价

  • Oracle Index索引无效的原因与解决方法

    索引无效原因 最近遇到一个Oracle SQL语句的性能问题,修改功能之前的运行时间平均为0.3s,可是添加新功能后,时间达到了4~5s.虽然几张表的数据量都比较大(都在百万级以上),但是也都有正确创建索引,不知道到底慢在了哪里,下面展开调查. 经过几次排除,把问题范围缩小在索引上,首先在确定索引本身没有问题的前提下,考虑索引有没有被使用到,那么新的问题来了,怎么知道指定索引是否被启用. 判断索引是否被执行 1. 分析索引 即将索引至于监控状态下,对索引进行分析.如下对 ID_TT_SHOHOU

  • Oracle导入导出数据的几种方式

    oracle导入导出数据 1.导出dmp格式文件 --备份某几张表 !!!! exp smsc/smsc file=/data/oracle_bak/dmp/bakup0209_2.dmp tables=\(send_msg_his,send_msg,recv_msg_his,recv_msg\) --备份整个数据库 !!!! --方式1 exp smsc/smsc file=/data/oracle_bak/dmp/bakupsmmc0209_2.dmp full=y --方式2 exp co

  • Mapper批量插入Oracle数据@InsertProvider注解

    Mapper: @Mapper @OracleRepository public interface OracleRadiusMapper{ @InsertProvider(type = OracleRadiusProvider.class , method = "insertRadiusDataBatch") int insertRadiusDataBatch(@Param("list")List<AcctInfo> acctInfoList); }

  • 抽取oracle数据到mysql数据库的实现过程

    在oracle数据库迁移至mysql数据库,除了oracle数据库模型移到mysql外,还一个重要环节就是要将oracle数据库的数据移到mysql数据库,本人尝试用过多款数据迁移程序,性能都不是很好的,于是自己动手写一个针对于oracle数据库数据迁移到mysql数据程序,其具体过程如下: 1.要抽取mysql表.字段及过滤条件的配制文件imp_data.sql 2.建立一个目录ETL_DIR 3.运行oracle数据库程序P_ETL_ORA_DATA,生成各表的csv数据文件,同时也生成一个

随机推荐