概述

BULK COLLECT 子句会批量检索结果,即一次性将结果集绑定到一个集合变量中,并从SQL引擎发送到PL/SQL引擎。通常可以在SELECT INTO、FETCH INTO以及RETURNING INTO子句中使用BULK COLLECT。

Oracle 使用 bulk collect 子句的用例

  • BULK COLLECT批量绑定 支持复合类型内部的集合类型

  • FETCH数据批量绑定

  • RETURNING 子句的批量绑定 不支持 INSERT returning 使用集合类型

  • 动态SQL批量绑定 不支持动态 INSERT 使用集合类型

#创建自定义数据类型 —— 集合类型、复合类型
create type numberlist is table of number; create type rec_data is object
(
ID integer,
nums numberlist
); #创建用例数据表
create table t01 (id)
as
select level as id
from dual
connect by LEVEL <= 100; #Oracle使用bulk collect子句的例子
declare
v_numlst numberlist;
v_recdat rec_data ;
CURSOR cur_dat IS
select id
from t01;
begin
/*在SELECT INTO中使用BULK COLLECT*/
begin
select id bulk collect
into v_numlst
from t01
where id <= 10;
dbms_output.put_line('v_numlst: ' || v_numlst.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*使用 BULK COLLECT INTO 嵌套的集合类型*/
begin
select id bulk collect
into v_recdat.NUMS
from t01
where id <= 20; dbms_output.put_line('v_recdat.NUMS: ' || v_recdat.NUMS.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*嵌套的集合类型变量赋值*/
begin
v_recdat.NUMS := v_numlst;
dbms_output.put_line('v_recdat.NUMS: ' || v_recdat.NUMS.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*在FETCH INTO中使用BULK COLLECT*/
begin
OPEN cur_dat;
FETCH cur_dat BULK COLLECT
INTO v_numlst limit 30;
close cur_dat;
dbms_output.put_line('fetch cursor: ' || v_numlst.COUNT);
exception
when
others then
dbms_output.put_line(sqlerrm);
end; /*在UPDATE RETURNING INTO中使用BULK COLLECT*/
begin
update t01
set id = id + 100
where id <= 40
returning id bulk collect into v_numlst;
rollback ;
dbms_output.put_line('update returning: ' || v_numlst.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*在DELETE RETURNING INTO中使用BULK COLLECT*/
begin
delete t01
returning id bulk collect into v_numlst;
rollback;
dbms_output.put_line('delete returning: ' || v_numlst.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*在动态SQL中使用BULK COLLECT*/
begin
EXECUTE IMMEDIATE 'select id from t01 where id <= 60 '
bulk collect into v_numlst;
rollback;
dbms_output.put_line('dynsql select: ' || v_numlst.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*在动态UPDATE中使用BULK COLLECT*/
begin
EXECUTE IMMEDIATE 'update t01 set id = id + 1 where id <= 70 returning id into :1'
RETURNING bulk collect INTO v_numlst;
rollback;
dbms_output.put_line('dynsql update returning: ' || v_numlst.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*在动态DELETE中使用BULK COLLECT*/
begin
EXECUTE IMMEDIATE 'delete t01 where id <= 80 returning id into :1'
RETURNING bulk collect INTO v_numlst;
rollback;
dbms_output.put_line('dynsql delete returning: ' || v_numlst.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; dbms_output.put_line('End ;');
end;
/ v_numlst: 10
v_recdat.NUMS: 20
v_recdat.NUMS: 10
fetch cursor: 30
update returning: 40
delete returning: 50
dynsql select: 60
dynsql update returning: 70
dynsql delete returning: 80
End ; PL/SQL procedure successfully completed.

KingbaseES 使用 bulk collect 子句的用例

  • BULK COLLECT批量绑定 不支持 复合类型内部的集合类型

  • FETCH数据批量绑定

  • RETURNING 子句的批量绑定 支持 INSERT returning 使用集合类型

  • 动态SQL批量绑定 支持动态 INSERT 使用集合类型

#创建自定义数据类型 —— 集合类型、复合类型
create type numberlist is table of number; create type rec_data is object
(
ID integer,
nums numberlist
); #创建用例数据表
create table t01 (id)
as
select level as id
from dual
connect by LEVEL <= 100; #Oracle使用bulk collect子句的例子
declare
v_numlst numberlist;
v_recdat rec_data ;
CURSOR cur_dat IS
select id
from t01;
begin
/*在SELECT INTO中使用BULK COLLECT*/
begin
select id bulk collect
into v_numlst
from t01
where id <= 10;
dbms_output.put_line('v_numlst: ' || v_numlst.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*使用 BULK COLLECT INTO 嵌套的集合类型*/
begin
select id bulk collect
into v_recdat.NUMS
from t01
where id <= 20; dbms_output.put_line('v_recdat.NUMS: ' || v_recdat.NUMS.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*嵌套的集合类型变量赋值*/
begin
v_recdat.NUMS := v_numlst;
dbms_output.put_line('v_recdat.NUMS: ' || v_recdat.NUMS.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*在FETCH INTO中使用BULK COLLECT*/
begin
OPEN cur_dat;
FETCH cur_dat BULK COLLECT
INTO v_numlst limit 30;
close cur_dat;
dbms_output.put_line('fetch cursor: ' || v_numlst.COUNT);
exception
when
others then
dbms_output.put_line(sqlerrm);
end; /*在INERT RETURNING INTO中使用BULK COLLECT*/
begin
insert into t01
select * from t01 where id <=35
returning id bulk collect into v_numlst;
rollback;
dbms_output.put_line('insert returning: ' || v_numlst.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*在UPDATE RETURNING INTO中使用BULK COLLECT*/
begin
update t01
set id = id + 100
where id <= 40
returning id bulk collect into v_numlst;
rollback ;
dbms_output.put_line('update returning: ' || v_numlst.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*在DELETE RETURNING INTO中使用BULK COLLECT*/
begin
delete t01
returning id bulk collect into v_numlst;
rollback;
dbms_output.put_line('delete returning: ' || v_numlst.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*在动态SQL中使用BULK COLLECT*/
begin
EXECUTE IMMEDIATE 'select id from t01 where id <= 60 '
bulk collect into v_numlst;
rollback;
dbms_output.put_line('dynsql select: ' || v_numlst.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*在动态INSERT中使用BULK COLLECT*/
begin
EXECUTE IMMEDIATE 'insert into t01 select * from t01 where id<=65 returning id'
RETURNING bulk collect INTO v_numlst;
rollback;
dbms_output.put_line('dynsql insert returning: ' || v_numlst.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*在动态UPDATE中使用BULK COLLECT*/
begin
EXECUTE IMMEDIATE 'update t01 set id = id + 1 where id <= 70 returning id into :1'
RETURNING bulk collect INTO v_numlst;
rollback;
dbms_output.put_line('dynsql update returning: ' || v_numlst.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; /*在动态DELETE中使用BULK COLLECT*/
begin
EXECUTE IMMEDIATE 'delete t01 where id <= 80 returning id into :1'
RETURNING bulk collect INTO v_numlst;
rollback;
dbms_output.put_line('dynsql delete returning: ' || v_numlst.COUNT);
exception
when others then
dbms_output.put_line(sqlerrm);
end; dbms_output.put_line('End ;');
end;
/ ANONYMOUS BLOCK
v_numlst: 10
cannot mix between single row and multi-row (BULK) in INTO list
v_recdat.NUMS: 10
fetch cursor: 30
insert returning: 35
update returning: 40
delete returning: 50
dynsql select: 60
dynsql insert returning: 65
dynsql update returning: 70
dynsql delete returning: 80
End ;

总结

  1. BULK COLLECT INTO 的目标对象必须是集合类型。

  2. limit减少内存占用,如果数据量较大一次性全部加载到内存中,对PGA来说压力太大,可采用limit的方法一次加载一定数量的数据,建议值通常为1000。 使用limit时注意,循环的时候如果用while cursor_name%found loop,对于最后一次fetch的数据量不足设定值,%found条件就会不成立,可以使用 集合变量.count > 0 作为判断条件。

bulk collect 在KingbaseES和Oracle的使用方法比较的更多相关文章

  1. oracle学习之bulk collect用法

    通过bulk collect减少loop处理的开销,使用Bulk Collect提高Oracle查询效率 Oracle8i中首次引入了Bulk Collect特性,该特性可以让我们在PL/SQL中能使 ...

  2. Oracle forall bulk collect批量数据更新

    对于数据量较大的插入操作可采用此种方法操作,注意: limit减少内存占用,如果数据量较大一次性全部加载到内存中,对PGA来说压力太大,可采用limit的方法一次加载一定数量的数据,建议值通常为100 ...

  3. Oracle数据库之FORALL与BULK COLLECT语句

    Oracle数据库之FORALL与BULK COLLECT语句 我们再来看一下PL/SQL块的执行过程:当PL/SQL运行时引擎处理一块代码时,它使用PL/SQL引擎来执行过程化的代码,而将SQL语句 ...

  4. 【ORACLE】Bulk Processing with BULK COLLECT and FORALL

    https://orablogspot.blogspot.com/2014/09/ https://blogs.oracle.com/oraclemagazine/bulk-processing-wi ...

  5. Oracle bulk collect into 的几种用法

    bulk collect 和 forall 联合应用写起来显得有些啰嗦,不过为了速度,多写两句又何妨 建立两个临时表 create table T_TEST ( TESTID NUMBER(19) n ...

  6. ORACLE fetch bulk collect into limit

    DECLARE TYPE rr IS REF CURSOR; TYPE r_emp IS RECORD( empno ), ename ), job ), mgr ), hiredate DATE, ...

  7. ORACLE PL/SQL开发--bulk collect的用法 .

    刚刚在inthirties老大的博客里看到这篇文章,写的不错,正好自己最近在学习PL/SQL,转过来学习学习. ============================================ ...

  8. Oracle批量查询、删除、更新使用BULK COLLECT提高效率

    BULK COLLECT(成批聚合类型)和数组集合type类型is table of 表%rowtype index by binary_integer用法笔记 例1: 批量查询项目资金账户号为 &q ...

  9. Oracle学习笔记之五sp1,PL/SQL之BULK COLLECT

    Bulk Collect特性可以让我们在PL/SQL中能使用批查询,批查询在某些情况下能显著提高查询效率. BULK COLLECT 子句会批量检索结果,即一次性将结果集绑定到一个集合变量中,并从SQ ...

随机推荐

  1. 在.NET 6.0上使用Kestrel配置和自定义HTTPS

    大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 本章是<定制ASP NET 6.0框架系列文章>的第四篇.在本章,我们 ...

  2. java反射之-Javabean与Map的互转

    1.BeanUntils工具类的准备 /** * @ClassName: BeanUtils * @Description: * @Author: songwp * @Date: 9:02 2022/ ...

  3. NC20861 兔子的逆序对

    NC20861 兔子的逆序对 题目 题目描述 兔子最近喜欢上了逆序对.一个逆序对 \((i,j)\) 需要满足 \(i < j\) 且 \(a_i > a_j\) .兔子觉得只是求一个序列 ...

  4. JDBCTools 第一个版本

    JDBCToolV1: package com.dgd.test; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax ...

  5. throws关键字_异常处理的第一种方式(交给别人处理)和try_catch_异常处理的第二种方式(自己处理)

    throws关键字:异常处理的第一种方式,交给别人处理 作用: 当方法内部抛出异常对象的时候,那么我们就必须处理这个异常对象 可以使用throws关键字处理异常对象, 会把异常对象声明抛出给方法的调用 ...

  6. letsencrypt更换pip源

    vim letsencrypt-auto 将DEFAULT_INDEX_BASE = 'https://pypi.python.org'改为DEFAULT_INDEX_BASE = 'http://m ...

  7. Scala学习第一天(Hello world)

    一.Scala介绍 1. Scala概念 Scala 是 Scalable Language 的简写,是一门多范式的编程语言 联邦理工学院洛桑(EPFL)的Martin Odersky于2001年基于 ...

  8. SPFA算法(SLF优化)2022.7.8更新

    SPFA可能会被卡掉,能用dijkstra就别用SPFA,代码较长,但我已尽力做到解释,请耐心看下去,存储为邻接表存储. #include<bits/stdc++.h> #define i ...

  9. 使用try_catch_finally处理流中的异常和JDK7流中的异常处理

    在jdk1.7之前使用try_catch_finally处理流中的异常 格式: try{ 可能会出现异常的代码 }catch(异常类变量 变量名){ 异常的处理逻辑 }finally{ 一定会执行的代 ...

  10. WPF 截图控件之绘制箭头(五)「仿微信」

    前言 接着上周写的截图控件继续更新 绘制箭头. 1.WPF实现截屏「仿微信」 2.WPF 实现截屏控件之移动(二)「仿微信」 3.WPF 截图控件之伸缩(三) 「仿微信」 4.WPF 截图控件之绘制方 ...