Simplememory

V1

2023/03/19阅读:9主题:橙心

Oracle中merge Into的用法

使用场景

在操作数据库时,数据存在的情况下,进行update操作;不存在的情况下,进行insert操作;在Oracle数据库中,能够使用merge into来实现。

基本语法

merge into table_name  alias1                  -- 目标表 可以用别名表示
using (table|view|sub_query) alias2            -- 数据源表 可以是表、视图、子查询等
on (join condition)                            -- 关联条件 
when matched then                              -- 当关联条件成立时 更新,删除,插入的where部分为可选 
  update table_name set col1 = colvalue  where ……        -- 更新操作
  delete from table_name  where  col2=colvalue  where……  -- 删除操作 
                                                         -- 可以只更新不删除 也可以只删除不更新
                                                         -- 如果更新和删除同时存在,删除的条件一定要在更新的条件内,否则数据不能删除
when not matched then                                    -- 当关联条件不成立时   
insert (col3) values (col3values)  where……               -- 关联条件进行插入操作

演示示例

为了演示,下面提供了两张测试表以及数据:

-- 测试表(1) tmp 
create table tmp
(
  id               VARCHAR2(20not null,
  tmp_name        VARCHAR2(120),
  tmp_date  VARCHAR2(8),
  is_delete        VARCHAR2(1),
  creator          VARCHAR2(24),
  created_at       NUMBER(20),
  updater          VARCHAR2(24),
  updated_at       NUMBER(20)
)
-- 测试表(2) temp
create table temp
(
  id               VARCHAR2(20not null,
  tmp_id        VARCHAR2(20),
  temp_name  VARCHAR2(120),
  temp_date  VARCHAR2(8),
  is_delete        VARCHAR2(1),
  creator          VARCHAR2(24),
  created_at       NUMBER(20),
  updater          VARCHAR2(24),
  updated_at       NUMBER(20)
)
-- 测试数据
truncate table tmp;
insert into tmp (ID, TMP_NAME, TMP_DATE, IS_DELETE, CREATOR, CREATED_AT, UPDATER, UPDATED_AT)values ('00001''tmp测试数据1''20220628''0''admin'nullnullnull);
insert into tmp (ID, TMP_NAME, TMP_DATE, IS_DELETE, CREATOR, CREATED_AT, UPDATER, UPDATED_AT)values ('00002''tmp测试数据2''20221223''0''admin'nullnullnull);
insert into tmp (ID, TMP_NAME, TMP_DATE, IS_DELETE, CREATOR, CREATED_AT, UPDATER, UPDATED_AT)values ('00003''tmp测试数据3''20210927''0''admin'nullnullnull);
truncate table temp;
insert into temp (ID, TMP_ID, TEMP_NAME, TEMP_DATE, IS_DELETE, CREATOR, CREATED_AT, UPDATER, UPDATED_AT)values ('E74C9EC''00001''temp测试数据1''20210823''0''admin'nullnullnull);
insert into temp (ID, TMP_ID, TEMP_NAME, TEMP_DATE, IS_DELETE, CREATOR, CREATED_AT, UPDATER, UPDATED_AT)values ('39978FC''00002''temp测试数据2''20211012''0''admin'nullnullnull);
insert into temp (ID, TMP_ID, TEMP_NAME, TEMP_DATE, IS_DELETE, CREATOR, CREATED_AT, UPDATER, UPDATED_AT)values ('88640EF''00006''temp测试数据3''20211121''0''admin'nullnullnull);
commit;

tmp表数据

temp表数据

两表的关联关系

select t.*,tt.* from tmp t,temp tt where t.id = tt.tmp_id;

merge into示例:

merge into temp  t   
using  tmp tt on (t.tmp_id = tt.id)
when matched then           
  update set t.temp_name ='xxkfz' where t.tmp_id = '00001'
  delete where (t.tmp_id  =  '00002')
when not matched then    
 insert (t.id, t.tmp_id,t.temp_name,t.temp_date,t.is_delete) values (sys_guid(),tt.id,tt.tmp_name,tt.tmp_date,tt.is_delete);
 commit;

几点说明:

  • 被更新的表写在merge into之后
  • 更新来源数据表写在using之后,并将相关字段查询出来,为查询结果定义别名
  • on 之后表示更新满足的条件
  • when matched then:表示当满足条件时要执行的操作
  • update set: 被更新表.被更新字段 = 更新表.更新字段---此更新语句不同于常规更新语句
  • when not matched then:表示当不满足条件时要执行的操作。
  • insert (被更新表.被更新字段,...) values (更新表.更新字段,...)
  • commit:表示提交事务

执行完成以上语句后,结果如下:

发现:temp表中tmp_id00002的数据没有被删除。

why ???

因为:如果更新和删除同时存在,删除的条件一定要在更新的条件内,否则数据不能删除!!!

为了更好的测试该场景,修改如下:

merge into temp  t    
using  tmp tt on (t.tmp_id = tt.id)
when matched then              
  update set t.temp_name ='xxkfz' where t.tmp_id  in ('00001','00002')
  delete where (t.tmp_id  =  '00002')
when not matched then    
 insert (t.id, t.tmp_id,t.temp_name,t.temp_date,t.is_delete) values (sys_guid(),tt.id,tt.tmp_name,tt.tmp_date,tt.is_delete);
 commit;

再次重置两表测试数据,执行以上语句,结果如下:

发现tmp_id00001的数据temp_name字段成功更新为xxkfztmp_id00002的数据成功删除!!!

对于没有匹配的数据:tmpid00003的数据也成功插入到temp表中!!!

分类:

后端

标签:

数据库

作者介绍

Simplememory
V1