Oracle:merge into用法

文章目录

merge into

MERGE 是 Oracle9i 新增的语法,根据源表对目标表进行匹配查询,匹配成功时更新,不成功时插入

比单独的 update + insert 的方式效率要更高,尤其是on条件下有唯一索引的时候,效率更高。

使用场景

在写数据同步的脚本时,常常会遇到这样的需求:存在时更新,不存在时插入

merge into语法

sql 复制代码
MERGE INTO [target-table] T  --目标表 可以用别名
USING [source-table] S  --数据源表 可以是表、视图、子查询
ON([conditional expression] )  --关联条件
WHEN MATCHED THEN --当关联条件成立时 更新、删除,插入的where部分为可选 
UPDATE [target-table] SET T.column = S.column WHERE 限制条件
DELETE [target-table] WHERE 限制条件
WHEN NOT MATCHED THEN --当关联条件不成立时   
INSERT (column,...) VALUES('',...)

判断源表 S 和目标表 T 是否满足 ON 中的条件,如果满足则用 S 表去更新 T 表,如果不满足,则将 S 表数据插入 T 表中。但是有很多可选项,如下:

  • 普通模式
  • 只 update 或者只 insert
  • 无条件 insert 实现
  • 带 delete 的 update

测试表

sql 复制代码
-- 目标表
CREATE TABLE target ( 
	ID NUMBER NOT NULL, 
	NAME VARCHAR2 ( 12 ) NOT NULL, 
	YEAR NUMBER 
);
-- 源表
CREATE TABLE source (
	ID NUMBER NOT NULL,
	AID NUMBER NOT NULL,
	NAME VARCHAR2 ( 12 ) NOT NULL,
	YEAR NUMBER,
	CITY VARCHAR2 ( 12 ) 
);
-- 插入测试数据
INSERT INTO target
VALUES
	( 1, 'liuwei', 20 );
INSERT INTO target
VALUES
	( 2, 'zhangbin', 21 );
INSERT INTO target
VALUES
	( 3, 'fuguo', 20 );
INSERT INTO source
VALUES
	( 1, 2, 'zhangbin', 30, '吉林' );
INSERT INTO source
VALUES
	( 2, 4, 'yihe', 33, '黑龙江' );
INSERT INTO source
VALUES
	( 3, 3, 'fuguo', '', '山东' );

普通模式

merge使用注意点

1、如果using中的语句查询不出来数据,是不会执行insert方法的,因为这个语法是根据using 中的查询数据进行判断

sql 复制代码
merge into student a
using (select id  from student where id = '7') s
on (a.id = s.id )
when matched then
  update set a.student_name = '小明二号'
when not matched then
  insert (id, student_name, fk_class) values ('7', '小明', '2')

2、on 中的条件记得过滤准确,不然可能会执行全表更新

sql 复制代码
merge into student a
using (select count(1)cot,id  from student group by id ) s
on (a.id = s.id and cot > 0)
when matched then
  update set a.student_name = '小明二号'
when not matched then
  insert (id, student_name, fk_class) values ('7', '小明', '2')

这么写的话可以看出明显的错误,只要是id相等且cot大于0,那么查询出的都大于0,会执行全表更新

3、on 中的条件不能是更新操作列,不然会报错:ora-38104

sql 复制代码
merge into student a
using (select '7' as id from dual) s
on (a.id = s.id)
when matched then
  update set a.id = '7'
when not matched then
  insert (id, student_name, fk_class) values ('7', '小明', '2');

参考:

https://blog.csdn.net/weixin_44657888/article/details/124591434

https://www.jianshu.com/p/8f51ce60d9ba

相关推荐
q***9941 小时前
Redis的Spring配置
数据库·redis·spring
S***y3961 小时前
MySQL视频
数据库·mysql
周杰伦fans2 小时前
[特殊字符] 代理模式超详细讲解 ——.NET
数据库·c#·代理模式
YJlio2 小时前
「C++ 40 周年」:从“野蛮生长的指针地狱”到 AI 时代的系统底座
c++·人工智能·oracle
TDengine (老段)2 小时前
TDengine 转换函数 TO_JSON 用户手册
android·大数据·数据库·json·时序数据库·tdengine·涛思数据
2301_800256113 小时前
第七章 空间存储与索引 知识点梳理3(空间填充曲线)
数据库·笔记·sql·postgresql
冰封剑心3 小时前
MiniCPM-V-2_6 (4-bit 量化)使用
java·前端·数据库
小满、3 小时前
MySQL :存储引擎原理、索引结构与执行计划
数据库·mysql·索引·mysql 存储引擎
x***13393 小时前
SQL Server 创建用户并授权
数据库·oracle
JIngJaneIL3 小时前
智慧物业|物业管理|基于SprinBoot+vue的智慧物业管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·论文·智慧物业管理系统