oracle insert into select 大数据量_Oracle的批量插入操作

MySQL中支持一条SQL语句执行批量插入,Oracle中支持的形式有些不同,但是殊途同归,用的就是insert all into语法。

创建测试表,

SQL> create table a1(id number, a varchar2(1), b varchar2(1), c varchar2(1), d varchar2(1));Table created.

可以用如下语句,执行批量插入,

SQL> insert all   2    into a1(id, a, b, c, d) values (1, 'a', 'a', 'a', 'a')     3    into a1(id, a, b, c, d) values (2, 'b', 'b', 'b', 'b')  4  select 1 from dual;2 rows created.

按照Oracle的解释,insert all into其实是根据子查询执行了每个insert into子句,注意到上面SQL中每个into子句用的值都是字面量,子查询"select 1 from dual"返回1条记录,支持每个insert into子句插入指定的1条记录,

“ALL into_clause: Specify ALL followed by multiple insert_into_clauses to perform an unconditional multitable insert. Oracle Database executes each insert_into_clause once for each row returned by the subquery.”

因此,如果在初始状态,子查询改成"select ... from a1",由于a1当前是空,返回记录数是0,所以这条SQL,插入就是0条,

SQL> insert all   2    into a1(id, a, b, c, d) values (1, 'a', 'a', 'a', 'a')   3    into a1(id, a, b, c, d) values (2, 'b', 'b', 'b', 'b')   4  select id, a, b, c, d from a1;0 rows created.

如果当前表中存在两条记录,

SQL> select * from a1;        ID A B C D---------- - - - -         1 a a a a         2 b b b b

再次执行insert all into,则会插入4条记录,因为子查询,返回2条记录,

SQL> insert all   2    into a1(id, a, b, c, d) values (1, 'a', 'a', 'a', 'a')   3    into a1(id, a, b, c, d) values (2, 'b', 'b', 'b', 'b')   4  select id, a, b, c, d from a1;4 rows created.

因此,最简单的形式,就是子查询用select 1 from dual。

但insert all into中子查询不支持使用序列,如下操作,提示错误,

SQL> insert all  2    into a1(id, a, b, c, d) values (seq_a1.nextval,  'a', 'a', 'a', 'a')  3    into a1(id, a, b, c, d) values (seq_a1.nextval,  'b', 'b', 'b', 'b')  4  select seq_a1.nextval, a, b, c, d from a1;select seq_a1.nextval, a, b, c, d from a1              *ERROR at line 4:ORA-02287: sequence number not allowed here

改为这种,能正常执行,

SQL> insert all   2    into a1(id, a, b, c, d) values (seq_a1.nextval,  'a', 'a', 'a', 'a')   3    into a1(id, a, b, c, d) values (seq_a1.nextval,  'b', 'b', 'b', 'b')   4  select 1 from dual;2 rows created.

但实际上,id得到的sequence值,是相同的,

SQL> select * from a1;        ID A B C D---------- - - - -         1 a a a a         1 b b b b

一种解决方式,是采用触发器,BEFORE INSERT在插入之前找到正确的序列,另外一种方式,就是创建函数,读取序列,他可以骗过Oracle,

SQL> create or replace function f_getseq return number as   2  v_seq number;  3  begin  4  select seq_a1.nextval into v_seq from dual;  5  return v_seq;  6  end;  7  /Function created.

此时能正常插入,而且id值,都正确了,

SQL> insert all   2    into a1(id, a, b, c, d) values (f_getseq,  'a', 'a', 'a', 'a')   3    into a1(id, a, b, c, d) values (f_getseq,  'b', 'b', 'b', 'b')   4  select 1 from dual;2 rows created.SQL> select * from a1;        ID A B C D---------- - - - -         1 a a a a         2 b b b b

近期的热文:

《数据库结构文档的生成利器》

《主键约束索引的奇葩现象》

《如何判断应用系统性能好不好?》

《Oracle Cloud创建19c数据库》

《SQL工具集-格式化结果的SQL》

《如何捕获问题SQL解决过度CPU消耗的问题》

《如何查看JVM运行的堆内存情况》

《Oracle删除字段的方式和风险,你都了解么?》

《登录缓慢的诡异问题》

《公众号600篇文章分类和索引》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值