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

相关推荐
技术宝哥3 小时前
Redis(2):Redis + Lua为什么可以实现原子性
数据库·redis·lua
学地理的小胖砸4 小时前
【Python 操作 MySQL 数据库】
数据库·python·mysql
dddaidai1235 小时前
Redis解析
数据库·redis·缓存
数据库幼崽5 小时前
MySQL 8.0 OCP 1Z0-908 121-130题
数据库·mysql·ocp
Amctwd5 小时前
【SQL】如何在 SQL 中统计结构化字符串的特征频率
数据库·sql
betazhou5 小时前
基于Linux环境实现Oracle goldengate远程抽取MySQL同步数据到MySQL
linux·数据库·mysql·oracle·ogg
lyrhhhhhhhh6 小时前
Spring 框架 JDBC 模板技术详解
java·数据库·spring
喝醉的小喵7 小时前
【mysql】并发 Insert 的死锁问题 第二弹
数据库·后端·mysql·死锁
付出不多8 小时前
Linux——mysql主从复制与读写分离
数据库·mysql
初次见面我叫泰隆8 小时前
MySQL——1、数据库基础
数据库·adb