bulk collect 在KingbaseES和Oracle的使用方法比较
概述
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 ;
总结
BULK COLLECT INTO 的目标对象必须是集合类型。
limit减少内存占用,如果数据量较大一次性全部加载到内存中,对PGA来说压力太大,可采用limit的方法一次加载一定数量的数据,建议值通常为1000。 使用limit时注意,循环的时候如果用while cursor_name%found loop,对于最后一次fetch的数据量不足设定值,%found条件就会不成立,可以使用 集合变量.count > 0 作为判断条件。
bulk collect 在KingbaseES和Oracle的使用方法比较的更多相关文章
- oracle学习之bulk collect用法
通过bulk collect减少loop处理的开销,使用Bulk Collect提高Oracle查询效率 Oracle8i中首次引入了Bulk Collect特性,该特性可以让我们在PL/SQL中能使 ...
- Oracle forall bulk collect批量数据更新
对于数据量较大的插入操作可采用此种方法操作,注意: limit减少内存占用,如果数据量较大一次性全部加载到内存中,对PGA来说压力太大,可采用limit的方法一次加载一定数量的数据,建议值通常为100 ...
- Oracle数据库之FORALL与BULK COLLECT语句
Oracle数据库之FORALL与BULK COLLECT语句 我们再来看一下PL/SQL块的执行过程:当PL/SQL运行时引擎处理一块代码时,它使用PL/SQL引擎来执行过程化的代码,而将SQL语句 ...
- 【ORACLE】Bulk Processing with BULK COLLECT and FORALL
https://orablogspot.blogspot.com/2014/09/ https://blogs.oracle.com/oraclemagazine/bulk-processing-wi ...
- Oracle bulk collect into 的几种用法
bulk collect 和 forall 联合应用写起来显得有些啰嗦,不过为了速度,多写两句又何妨 建立两个临时表 create table T_TEST ( TESTID NUMBER(19) n ...
- ORACLE fetch bulk collect into limit
DECLARE TYPE rr IS REF CURSOR; TYPE r_emp IS RECORD( empno ), ename ), job ), mgr ), hiredate DATE, ...
- ORACLE PL/SQL开发--bulk collect的用法 .
刚刚在inthirties老大的博客里看到这篇文章,写的不错,正好自己最近在学习PL/SQL,转过来学习学习. ============================================ ...
- Oracle批量查询、删除、更新使用BULK COLLECT提高效率
BULK COLLECT(成批聚合类型)和数组集合type类型is table of 表%rowtype index by binary_integer用法笔记 例1: 批量查询项目资金账户号为 &q ...
- Oracle学习笔记之五sp1,PL/SQL之BULK COLLECT
Bulk Collect特性可以让我们在PL/SQL中能使用批查询,批查询在某些情况下能显著提高查询效率. BULK COLLECT 子句会批量检索结果,即一次性将结果集绑定到一个集合变量中,并从SQ ...
随机推荐
- 一篇文章带你深入浅出Vuex
在写Vuex之前,我们先用一个简单的例子来实现一个小demo 大家都知道Vue的父传子用在很多场景,比如像这样: 父组件: <template> <div id="app& ...
- SAP 实例- 下拉框
效果图 源代码 REPORT rsdemo_dropdown_listbox . DATA init. TABLES scarr. TABLES spfli. TABLES sflight. TABL ...
- idea中enter键不能换行
idea中enter键不能换行 按enter键只能往下移动 如下图 解决办法: 方式一:按住window + Insert 方式二: 按住Fn + Insert 两种方式总有一种可以 之后就可以按en ...
- NC16746 神奇盘子
NC16746 神奇盘子 题目 题目描述 有一个神奇的盘子,形状为圆形.盘子上面爬着一个大象(视作一个点).由于现实的扭曲,当大象在盘子某个直径的一端的时候,可以瞬间传送至直径的另一端.现在大象想去盘 ...
- NC50999 表达式计算4
NC50999 表达式计算4 题目 题目描述 给出一个表达式,其中运算符仅包含+,-,*,/,^(加 减 乘 整除 乘方)要求求出表达式的最终值 数据可能会出现括号情况,还有可能出现多余括号情况 数据 ...
- NC16618 [NOIP2008]排座椅
NC16618 [NOIP2008]排座椅 题目 题目描述 上课的时候总有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情.不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下 ...
- PTA(BasicLevel)-1031 查验身份证
一.问题定义 一个合法的身份证号码由17位地区.日期编号和顺序编号加1位校验码组成.校验码的计算规则如下:首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,1 ...
- SpringMVC 概述
1. SpringMVC 概述 1) Spring 为展现层提供的基于 MVC 设计理念的优秀的 Web 框架,是目前最主流的MVC 框架之一 .MVC,M:model,模型层,指的是项目中的实体Ja ...
- DNS 系列(二):DNS 记录及工作方式,你了解吗?
在上一篇<DNS 系列(一):为什么更新了 DNS 记录不生效?>中,我们主要讲解了 DNS 和 DNS 传播,知道了网络通信主要通过 IP 地址来进行,而域名系统(DNS)则是保证用户在 ...
- 【cartographer_ros】七: 主要配置参数说明
上一节介绍了路标Landmark数据的订阅和发布,各类数据的发布和订阅基本阐述完毕. 本节会介绍cartographer的主要配置参数,研究这些参数的使用和对算法的影响. 目录 1,map_build ...