Bulk Collect特性可以让我们在PL/SQL中能使用批查询,批查询在某些情况下能显著提高查询效率。

  • BULK COLLECT 子句会批量检索结果,即一次性将结果集绑定到一个集合变量中,并从SQL引擎发送到PL/SQL引擎。

  • 可以在select into,fetch into,returning into语句使用bulk collect。

  • 注意在使用bulk collect时,所有的into变量都必须是collections。

1. 背景

以前曾经做过一个需求,数据库中有两张表,A表是2千万记录,B表是1千万条记录,它们之间存在某种联系,要求程序将它们关联起来,以A表为基准。

然后就是PL/SQL写了个程序(参考方式一代码),运行巨慢,且会报内存不足(在自己的笔记本上跑的)。后来用了BULK COLLECT,有了很大改善。以前的代码已经没有了运行的环境,代码也只保留了框架下来,贴在这里,做个记号。

方式一,最早的实现方式:

DECLARE
--定义一个RECORD类型用来存储记录,为节省内存,只存储需要处理的字段
TYPE SIM_RECORD is record(SYSCODE SIM.SYSCODE%TYPE,CUSNAME SIM.CUSNAME%TYPE,CUSADDR SIM.CUSADDR%TYPE,PHONE SIM.PHONE%TYPE
);
V_SIM_RECORD SIM_RECORD;--定义若干用到的其它变量
v_start_syscode number := 1;
v_process_records number := 1000000;
v_count number := 0;--定义游标
CURSOR SIMCursor IS SELECT SYSCODE,CUSNAME,CUSADDR,PHONE
FROM SIM
WHERE SYSCODE>=v_start_syscode AND SYSCODE<v_start_syscode+v_process_records;
BEGIN--打开游标OPEN SIMCursor;LOOP--读取游标FETCH SIMCursor INTO V_SIM_RECORD;EXIT WHEN SIMCursor%NOTFOUND;--防止更新出现异常,所以将DML语句进行封装,以避免某条记录出现错误而导致退出循环BEGIN--主处理语句,省略--取得值通过:V_SIM_RECORD.SYSCODE等这样的方式获取--每处理20000条记录,输出一些统计信息v_count := v_count+1;IF mod(v_count,20000)=0 THENdbms_output.put_line(V_SIM_RECORD.SYSCODE||'['||v_count||']');END IF;EXCEPTIONWHEN OTHERS THENdbms_output.put_line('sqlerrm-->' ||sqlerrm);END;END LOOP;--关闭游标CLOSE SIMCursor;
EXCEPTIONWHEN OTHERS THENdbms_output.put_line('sqlerrm-->' ||sqlerrm);
END;

方式二,在select into语句中使用bulk collect

DECLARE
--定义存储数据的数据结构(collections)
TYPE SIM_TABLE IS TABLE OF SIM%ROWTYPE;
T_SIM_TABLE SIM_TABLE;--定义若干用到的其它变量
v_start_syscode number := 1;
v_process_records number := 1000000;
v_count number := 0;BEGIN--在select into语句中使用bulk collect,一次性取得SELECT * BULK COLLECT INTO T_SIM_TABLE  FROM SIM  WHERE SYSCODE>=v_start_syscode AND SYSCODE<v_start_syscode+v_process_records;FOR i IN 1 .. T_SIM_TABLE.count LOOP--防止更新出现异常,所以将DML语句进行封装,以避免某错误记录导致退出循环BEGIN--主处理语句,省略--取得值通过:T_SIM_TABLE(i).PHONE等这样的方式获取--每处理20000条记录,输出一些统计信息v_count := v_count+1;IF mod(v_count,20000)=0 THENdbms_output.put_line(T_SIM_TABLE(i).PHONE||'['||v_count||']');END IF;EXCEPTIONWHEN OTHERS THENdbms_output.put_line('sqlerrm-->' ||sqlerrm);END;END LOOP;
EXCEPTIONWHEN OTHERS THENdbms_output.put_line('sqlerrm-->' ||sqlerrm);
END;

方式三,在fetch into中使用bulk collect

DECLARE
--定义存储数据的数据结构(collections)
TYPE SIM_TABLE IS TABLE OF SIM%ROWTYPE;
T_SIM_TABLE  SIM_TABLE;--定义若干用到的其它变量
v_start_syscode number := 1;
v_process_records number := 1000000;
v_count number := 0;--定义游标
CURSOR SIMCursor IS SELECT * FROM SIM where SYSCODE>=v_start_syscode AND SYSCODE<v_start_syscode+v_process_records;
BEGINOPEN SIMCursor;LOOPEXIT WHEN SIMCursor%NOTFOUND;--在fetch into中使用bulk collect,分批次取得        FETCH SIMCursor BULK COLLECT INTO T_SIM_TABLE LIMIT 50000;FOR i IN 1 .. T_SIM_TABLE.count LOOP--防止更新出现异常,所以将DML语句进行封装,以避免某错误记录导致退出循环BEGIN--主处理语句,省略--取得值通过:T_SIM_TABLE(i).PHONE等这样的方式获取--每处理20000条记录,输出一些统计信息v_count := v_count+1;IF mod(v_count,20000)=0 THENdbms_output.put_line(T_SIM_TABLE(i).PHONE||'['||v_count||']');END IF;EXCEPTIONWHEN OTHERS THENdbms_output.put_line('sqlerrm-->' ||sqlerrm);END;END LOOP;END LOOP;CLOSE SIMCursor;
EXCEPTIONWHEN OTHERS THENdbms_output.put_line('sqlerrm-->' ||sqlerrm);
END;

转载于:https://www.cnblogs.com/nayitian/p/3221365.html

Oracle学习笔记之五sp1,PL/SQL之BULK COLLECT相关推荐

  1. oracle学习笔记5:pl/sql流程控制语句

    pl/sql编程中的流程控制语句主要有if语句,case语句以及循环语句 下面将逐个介绍这几个语句 1.if语句 -- 根据员工工资来判断奖金的多少,工资在5000以上的奖金500,工资在3000-5 ...

  2. PostgreSQL Oracle 兼容性之 - PL/SQL FORALL, BULK COLLECT

    Oracle PL/SQL 开发的童鞋,一定对O家的bulk批量处理的性能很是赞赏吧. 但是PostgreSQL用户请不要垂涎,作为学院派和工业界的一颗璀璨明珠. 开源数据库PostgreSQL,也有 ...

  3. oracle学习(二)pl/sql基础

    pl/sql组成:DDL DML DCL pl/sql特点: SQL&PL/SQL编译器集成PL/SQL,支持SQL所有范围的语法 支持CASE语句和表达式 继承和动态方法释放 类型进化.属性 ...

  4. Oracle学习 第20天 PL/SQL导入

    我就知道导入也有很多坑... DROP USER XXX CASCADE; --删除用户CREATE USER XXX IDENTIFIED BY XXX --创建用户GRANT DBA TO XXX ...

  5. oracle update单引号,Oracle学习笔记:update的字段中包括单引号

    平时update的时候直接更改字段内的值,例如: update table_temp set name = 'Hider' where id = 100; 但更新后的值中包括单引号,则不能按以上方式进 ...

  6. Oracle学习笔记(最重要的是PL/SQL编程)

    一:Oracle认证,与其它数据库比较,安装 Oracle安装会自动的生成sys用户和system用户: (1) sys用户是超级用户,具有最高权限,具有sysdba角色,有create databa ...

  7. Oracle学习笔记---(一)

    Oracle学习笔记---(一) 一 1.Oracle简介     Oracle是以高级结构化查询语言(SQL)为基础的大型关系数据库:是一个对象关系数据库管理系统(ORDBMS).它提供了关系数据库 ...

  8. Oracle学习笔记 字符集概述

    Oracle 学习笔记 字符集概述 这节课开始讲oracle里面的字符集 偏重于原理和简单的一些判断以及实现 字符集它涉及到很多的东西 比如建库和操作系统环境 这节课把字符集的原理性的东西以及常见的操 ...

  9. oracle:oracle学习笔记(四)循环、光标、异常、瀑布模型

    oracle学习笔记:循环.光标.异常 文章目录 打印Hello World 定义基本变量 引用型变量(单行)` my_name emp.ename%type ` 记录型变量(多行) `emp_rec ...

最新文章

  1. python操作word文档(python-docx)
  2. java测试不成功_为什么我的Java布尔测试总是失败?
  3. 在 Java 中利用 redis 实现 LBS 服务
  4. Mysql实现企业级日志管理、备份与恢复
  5. android socket 框架c#,C#与Android Socket通信
  6. ARCore之路-环境配置
  7. 应用,传输层协议和端口对应关系
  8. win10 +ubuntu20.04双系统安装:双硬盘+nvidia独立显卡
  9. [译]eBay Elasticsearch性能调优实践
  10. C#textbox和label显示皆透明如何修改/让字体和背景透明
  11. nginx 启动、重启、配置重新加载
  12. 官方MySQL解压版安装说明
  13. The 2019 ICPC Asia Nanjing Regional Contest(A、C、K)
  14. 关于基于Linux的电子词典的编写
  15. PMBOK泛读(第十一章) - 项目风险管理
  16. 什么是质量?你真的了解吗?
  17. ECshop导入淘宝数据包乱码问题解决方法
  18. 在 isilon 的 Samba 中接入 LDAP 认证并严格控制权限
  19. oracle根据秒数生成多少小时多少分钟多少秒
  20. mysql更新多字段sql_SQL UPDATE 更新语句用法(单列与多列)

热门文章

  1. python在d盘增加环境变量配置_怎样配置Python环境变量
  2. Docker必备国内镜像
  3. 【NOIP2000】【vijos1347】乘积最大
  4. 证券计算机行业研究,20210630-首创证券-计算机行业深度报告:物联网,研究框架.pdf...
  5. 计算机社团技术部部长述职报告,社团部长个人工作总结(精选6篇)
  6. php7版本搭建sqli labs,CentOS 7 LAMP搭建并且部署sqli-labs
  7. [leetcode]831. 隐藏个人信息
  8. OpenGL基础39:GLSL内建变量与接口块
  9. 游戏物体复用:对象池(以Unity3D为例)
  10. 牛客网暑期ACM多校训练营(第四场): B. Interval Revisited(DP)