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 ...
随机推荐
- JavaScript写放大镜效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- python基础知识-day7(文件操作)
1.文件IO操作: 1)操作文件使用的函数是open() 2)操作文件的模式: a.r:读取文件 b.w:往文件里边写内容(先删除文件里边已有的内容) c.a:是追加(在文件基础上写入新的内容) d. ...
- SAP Web Dynpro-集成消息
您可以使用消息管理器将消息集成到消息日志中. 您可以使用Web Dynpro代码向导打开消息管理器. 您可以从工具栏中打开Web Dynpro代码向导. 当您的ABAP工作台处于更改模式或编辑视图或控 ...
- 排名前三——python 开源 IDE
写在前面的一些P话: Python无处不在 ,似乎它支持从主要网站到桌面实用程序到企业软件的所有功能. Python已经被用来编写流行的软件项目,如dnf / yum,OpenStack,OpenSh ...
- [MRCTF2020]Ezpop-1|php序列化
1.打开题目获取到源代码信息,如下: Welcome to index.php <?php //flag is in flag.php //WTF IS THIS? //Learn From h ...
- 使用EasyExcel导出图片及异常处理
1.使用String类型导出 定义自己的Converter,不使用默认的StringImageConverter 如果图片路径为空或者图片路径是错误的,返回相应的内容 import java.io ...
- HTTP Status 405 - Request method 'GET' not supported?(尚硅谷Restful案例练习关于Delete方法出现的错误)
哈罗大家好,最近在如火如荼的学习java开发----Spring系列框架,当学习到SpringMVC,动手实践RESTFUL案例时,发现了以上报错405,get请求方法没有被支持. 首先第一步,我查看 ...
- Tapdata Real Time DaaS 技术详解 PART I :实时数据同步
摘要:企业信息化过程形成了大量的数据孤岛,这些并不连通的数据孤岛是企业数字化转型的巨大挑战.Tapdata Real Time DaaS 采用的CDC模式,具有巨大的优势,同时是一个有技术壁垒的活 ...
- springboot2+jpa+oracle实例
pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="ht ...
- NAT模式 LVS负载均衡群集部署
NAT模式 LVS负载均衡群集部署的操作步骤 实验环境准备: 负载调度器:内网关 ens33:172.16.10.1,外网关 ens37:12.0.0.1 Web节点服务器1:172.16.10.10 ...