我们操作数据库的时候,有时候会遇到insertOrUpdate这种需求。
如果数据库中存在数据就update,如果不存在就insert。
以前的时候,需要额外select查询一下,如果有数据就update,如果没有数据就insert。
而现在Orcale数据库都提供了 MERGE 方法来处理这种需求。
MERGE 命令使用一条语句从一个或者多个数据源中完成对表的更新和插入数据。
MERGE 语法:
MERGE INTO [your table-name] [rename your table here] USING ( [write your query here] )[rename your query-sql and using just like a table] ON ([conditional expression here] AND [...]...) WHEN MATCHED THEN [here you can execute some update sql or something else ] WHEN NOT MATCHED THEN [execute something else here ! ]
这里我们创建两张学生信息表,以此为例来进行说明:
-- Create table
create table STUDENT_1
(
id VARCHAR2(64) not null,
code VARCHAR2(30) not null,
name VARCHAR2(100) not null,
age NUMBER(3) not null,
created_by VARCHAR2(64) not null,
creation_date DATE not null,
last_updated_by VARCHAR2(64) not null,
last_update_date DATE not null,
last_update_ip VARCHAR2(64) not null,
version NUMBER(16) not null
)
tablespace MES614
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 16
next 8
minextents 1
maxextents unlimited
);
-- Add comments to the table
comment on table STUDENT_1
is '1班学生信息表';
-- Add comments to the columns
comment on column STUDENT_1.id
is 'ID';
comment on column STUDENT_1.code
is '学生证号';
comment on column STUDENT_1.name
is '学生姓名';
comment on column STUDENT_1.age
is '年龄';
comment on column STUDENT_1.created_by
is '创建人';
comment on column STUDENT_1.creation_date
is '创建日期';
comment on column STUDENT_1.last_updated_by
is '最后更新人';
comment on column STUDENT_1.last_update_date
is '最后更新时间';
comment on column STUDENT_1.last_update_ip
is '最后更新IP';
comment on column STUDENT_1.version
is '版本';
-- Create/Recreate primary, unique and foreign key constraints
alter table STUDENT_1
add constraint PK_STUDENT_1 primary key (ID)
using index
tablespace MES614
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
next 1M
minextents 1
maxextents unlimited
);
学生信息表2除了和学生信息表1名称不一样之外,结构完全一致,所以这里就不在把学生信息表2(student_2)的建表语句放上来了。(Mes614是表空间名)
我们先手动的在student_2表中插入一些数据,然后先单独的写两个sql,分别将student_2中的数据插入或者更新到student_1中:
--将student_2中的数据插入到student_1中
insert into student_1
(id,
code,
name,
age,
created_by,
creation_date,
last_updated_by,
last_update_date,
last_update_ip,
version)
select t.id,
t.code,
t.name,
t.age,
t.created_by,
t.creation_date,
t.last_updated_by,
t.last_update_date,
t.last_update_ip,
t.version
from student_2 t
--where ...
--将student_1中数据除ID外随便乱改,然后通过merge into sql将其更新回来
merge into student_1 t
using (select t1.id,
t1.code,
t1.name,
t1.age
from student_2 t1) me --这里可以只查出需要的字段
on (t.id = me.id)
when matched then --当on()中条件成立时执行
update
set t.code = me.code,
t.name = me.name,
t.age = me.age,
t.version = t.version + 1;
下面我们就用merge into sql来同时进行插入和更新操作:
merge into student_1 t
using (select t1.id,
t1.code,
t1.name,
t1.age,
t1.created_by,
t1.creation_date,
t1.last_updated_by,
t1.last_update_date,
t1.last_update_ip,
t1.version
from student_2 t1) me --这里可以只查出需要的字段
on (t.id = me.id)
when matched then --当on()中条件成立时执行
update
set t.code = me.code,
t.name = me.name,
t.age = me.age,
t.version = t.version + 1
when not matched then --当on()中条件不成立时执行这部分
insert
(id,
code,
name,
age,
created_by,
creation_date,
last_updated_by,
last_update_date,
last_update_ip,
version)
values
(me.id,
me.code,
me.name,
'22',
me.created_by,
me.creation_date,
me.last_updated_by,
me.last_update_date,
me.last_update_ip,
me.version);
注意事项:
Merge Into的原理是,从using 搜出来的结果逐条与on条件匹配,然后决定是update还是Insert。 当USING后面的sql没有查询到数据的时候,Merge Into语句是不会执行update和Insert操作的。
所以要想让Merge Into正常运行,要保证USING 后面的SELECT有数据。
转自:https://www.cnblogs.com/1012hq/p/11364698.html
