首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Oracle insert all 详解

Oracle insert all 详解

作者头像
全栈程序员站长
发布2022-09-16 17:19:41
发布2022-09-16 17:19:41
72100
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

文章目录

1 概述

代码语言:javascript
代码运行次数:0
运行
复制
1. 作用:'正确、高效' 的将 '同一批数据' 插入至 '不同的表' 中

2. 好处
   (1) '正确':避免数据差异
   (2) '高效':优于写多个 insert into(因为无论插入多少张表,'主表' 只会被读取一次)
   
3. 场景,若需求:将表 t 中的数据 '同时插入' 至表 t1、t2
   若不知晓 insert all 语句,咱可能会使用 insert into 两次
   insert into t1 select * from t;
   insert into t2 select * from t;

   问题:在两次 insert 过程中,有可能 t 表的数据发生了改变,
   从而导致 t1、t2 '得到的数据不一致'。
   
   解决办法:insert all

2 insert 的两种形式

代码语言:javascript
代码运行次数:0
运行
复制
1. insert first: 仅对 '第一个' 匹配成功项进行插入
2. insert all  : 对 '每个' 匹配成功项都进行插入

基础数据准备:

代码语言:javascript
代码运行次数:0
运行
复制
create table stu_info (
   sno   number(3),
   sname varchar2(30),
   sex   varchar2(2)
);

insert into stu_info(sno, sname, sex) values(1, '瑶瑶', '女');
insert into stu_info(sno, sname, sex) values(2, '优优', '男');
insert into stu_info(sno, sname, sex) values(3, '倩倩', '女');
commit;

-- 两张测试表
create table stu_info_1 as select * from stu_info where 1 = 2;
create table stu_info_2 as select * from stu_info where 1 = 2;

2.1 insert first

代码语言:javascript
代码运行次数:0
运行
复制
-- 仅对 '第一个' 匹配成功项进行插入
insert first
  when sno >= 2 then -- 不能用别名哦,如:t.sno
    into stu_info_1(sno, sname, sex)
  when sno >= 3 then
    into stu_info_2(sno, sname, sex) 
select t.sno, t.sname, t.sex from stu_info t;

查询结果:

代码语言:javascript
代码运行次数:0
运行
复制
select * from stu_info;
select * from stu_info_1;
select * from stu_info_2;

图示:仅对 ‘第一个’ 匹配成功项进行插入

2.2 insert all

代码语言:javascript
代码运行次数:0
运行
复制
-- 对 '每个' 匹配成功项都进行插入
insert all
  when sno >= 2 then -- 不能写别名哦,如:t.sno
    into stu_info_1(sno, sname, sex)
  when sno >= 3 then
    into stu_info_2(sno, sname, sex) 
select t.sno, t.sname, t.sex from stu_info t;

查询结果:对 ‘每个’ 匹配成功项都进行插入

3 数据一致性(同时插入)

3.1 验证:insert into 数据不一致

代码语言:javascript
代码运行次数:0
运行
复制
1. 模拟:将表 stu_info 中的数据同时插入 stu_info_1 和 stu_info_2

2. 分三个窗口模拟 '同时插入(并行)'
   (1) 窗口1: 将 stu_info 数据插入 stu_info_1(模拟时长 30 s)
   (2) 窗口2: 将 stu_info 数据插入 stu_info_2(模拟时长 30 s)
   (3) 窗口3:此时更新 stu_info 记录,使之影响 tu_info_1 和 stu_info_2(上述模拟时长内) 

3. 清空表 stu_info_1、stu_info_2 -- 若有数据
   truncate table stu_info_1;
   truncate table stu_info_2;

4. dbms_lock 包权限 -- 若无权限,sys 用户授权
   -- conn system/system@orcl as sysdba
   grant execute on sys.dbms_lock to scott;

图示:

窗口1:插入 stu_info_1,更新 sno = 2 的记录时,等待(模拟执行时长)

代码语言:javascript
代码运行次数:0
运行
复制
declare
begin
  for i in 1 .. 3 loop
  
    if i = 2 then
      dbms_lock.sleep(30); -- 模拟执行时长:30 秒
    end if;
  
    insert into stu_info_1
      (sno, sname, sex)
      select t.sno, t.sname, t.sex from stu_info t where t.sno = i;
    commit;
  
  end loop;
end;

窗口2:插入 stu_info_1,更新 sno = 3 的记录时,等待(模拟执行时长)

代码语言:javascript
代码运行次数:0
运行
复制
declare
begin
  for i in 1 .. 3 loop
  
    if i = 3 then
      dbms_lock.sleep(30); -- 模拟执行时长:30 秒
    end if;
  
    insert into stu_info_2
      (sno, sname, sex)
      select t.sno, t.sname, t.sex from stu_info t where t.sno = i;
    commit;
  
  end loop;
end;

窗口3:更新 stu_info 记录,使之影响 tu_info_1 和 stu_info_2(上述模拟时长内)

代码语言:javascript
代码运行次数:0
运行
复制
update stu_info t set t.sname = 'update_2', t.sex = '22' where t.sno = 2;
commit;

测试结果:stu_info_1 和 stu_info_2 两者记录不一致!

3.2 验证:insert all 数据一致

代码语言:javascript
代码运行次数:0
运行
复制
1. 同理,可分为 两个窗口测试

2. 清空表 stu_info_1、stu_info_2,并还原 stu_info 的数据

窗口1:插入数据至 stu_info_1 和 stu_info_1

代码语言:javascript
代码运行次数:0
运行
复制
declare
begin
   for i in 1 .. 3 loop
   
      if i = 2 then
         dbms_lock.sleep(30); -- 模拟执行时长:30 秒
      end if;
   
      insert all 
         into stu_info_1(sno, sname, sex) 
         into stu_info_2(sno, sname, sex)
      select t.sno, t.sname, t.sex from stu_info t where t.sno = i; 
      commit;
   
   end loop;
end;

窗口2:更新 stu_info 记录,使之影响 tu_info_1 和 stu_info_2(上述模拟时长内)

代码语言:javascript
代码运行次数:0
运行
复制
update stu_info t set t.sname = 'update_3', t.sex = '33' where t.sno = 3;
commit;

测试结果:

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/160934.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 1 概述
  • 2 insert 的两种形式
    • 2.1 insert first
    • 2.2 insert all
  • 3 数据一致性(同时插入)
    • 3.1 验证:insert into 数据不一致
    • 3.2 验证:insert all 数据一致
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档