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 ...
随机推荐
- SAP APO-部署选项
SAP SCM Server安装提供SAP APO功能模块的所有功能. 在SAP APO的附加部署模型中,以下组件可用作SAP APO工具的一部分- OTE-在附加部署模型中,无法通过SAP SCM服 ...
- c# 怎样能写个sql的解析器
c# 怎样能写个sql的解析器 本示例主要是讲明sql解析的原理,真实的源代码下查看 sql解析器源代码 详细示例DEMO 请查看demo代码 前言 阅读本文需要有一定正则表达式基础 正则表达式基础教 ...
- 在docker中打开redis 客户端 cli
首先交互方式进入redis容器 docker exec -it redis /bin/bash 随后运行客户端 redis-cli
- 『现学现忘』Git后悔药 — 29、版本回退git reset --mixed命令说明
git reset --mixed commit-id命令:回退到指定版本.(mixed:混合的,即:中等回退.) 该命令不仅修改了分支中HEAD指针的位置,还将暂存区中数据也回退到了指定版本. 但是 ...
- 《SVDNet for Pedestrian Retrieval》理解
<SVDNet for Pedestrian Retrieval>理解 Abstract: 这篇文章提出了一个用于检索问题的SVDNet,聚焦于在行人再识别上的应用.我们查看卷积神经网络中 ...
- C++ 模板和泛型编程(掌握Vector等容器的使用)
1. 泛型 泛型在我的理解里,就是可以泛化到多种基本的数据类型,例如整数.浮点数.字符和布尔类型以及自己定义的结构体.而容器就是提供能够填充任意类型的数据的数据结构.例如vector就很类似于pyth ...
- PTA(BasicLevel)-1023 组个最小数
一. 问题定义 给定数字 0-9 各若干个.你可以以任意顺序排列这些数字,但必须全部使用.目标是使得最后得到的数尽可能小(注意 0 不能做首位). 例如:给定两个 0,两个 1,三个 5,一个 8,我 ...
- CSS进阶内容—浮动和定位详解
CSS进阶内容-浮动和定位详解 我们在学习了CSS的基本知识和盒子之后,就该了解一下网页的整体构成了 当然如果没有学习之前的知识,可以到我的主页中查看之前的文章:秋落雨微凉 - 博客园 CSS的三种布 ...
- Deep Learning-深度学习(二)
深度学习入门 1.随机梯度下降 在之前的学习过程当中,对于损失函数的最为重要的参数的梯度的更新是基于数据集中的所有数据,每一个数据都会进行到计算过程当中去,在本案例中,因为波士顿房价预测这个案例所涉及 ...
- MLX90640 红外热成像仪测温模块简要介绍说明
MLX90640 红外热成像仪测温模块简要介绍说明 (1) A 型和 B 型的区别 区别主要有以下几点 视场角不同: A 型为 110*75° , B 型为 55*35° ,通俗一点讲就是 A 型是广 ...