碰到的问题,有一个员工表,存储着员工的各种信息。
我要写一个过程,传进去员工的名字,打印该员工的信息。

create or replace procedure  getInfo(name emp.ename%type) as
--  ei 相当于empInfomationei emp%rowtype;
beginselect * into ei from emp where emp.ename=name;dbms_output.put_line(ei.empno||','||ei.ename||','||ei.job||','||ei.mgr||','||ei.hiredate||','||ei.sal||','||nvl(ei.comm,0)||','||ei.deptno);exception when too_many_rows thendbms_output.put_line('多行数据');when no_data_found thendbms_output.put_line('无该名字');
end;

但这样有个问题,无论传入的员工的名字是多少,都会输出–多行数据。
原因是select * into ei是一条一条赋值的,自然不是一行。
如果能将一条员工信息存在一个变量里面就好了。
需要用到bulk collect

create procedure getInfo(ename emp.ename%type) astype arrtype is table of emp%rowtype index by binary_integer;fault exception;arry arrtype;beginselect * bulk collect into arry from emp where getInfo.ename=emp.ename;if arry.count=0 then raise fault;end if;for i in 1..arry.count loopdbms_output.put_line(arry(i).empno||','||arry(i).ename||','||arry(i).job||','||arry(i).mgr||','||arry(i).hiredate||','||arry(i).sal||','||nvl(arry(i).comm,0)||','||arry(i).deptno);end loop;exceptionwhen fault thendbms_output.put_line('没找到');           end;

目录

  • bulk collect介绍
  • 用在select into 里面
  • 用在fetch 里面
  • 用在 returning into clause里

bulk collect介绍

BULK COLLECT子句是批量SQL的一项功能,从SQL向PL/SQL返回的是一簇数据,而不是一次一条。这样效率更高。(而forall 是sends DML statements from PL/SQL to SQL in batches rather than one at a time.)
可以出现在

  1. select into statement
  2. fetch statement
  3. returning into clause of
    1. delete statement
    2. insert statement
    3. update statement
    4. execute immediate statement

需要注意的是,当bulk collect 语句没有行数返回时,PL/SQL不会引发异常,所以看你的需要来定义异常。(PL/SQL does not raise an exception when a statement with a BULK COLLECT clause returns no rows)

用在select into 里面

The SELECT INTO statement with the BULK COLLECT clause (also called
the SELECT BULK COLLECT INTO statement) selects an entire result set
into one or more collection variables.

select bulk collect into语句选择一整个结果集到一个或者更多的集合变量中。
这个collection variables可以使用数组。

DECLARETYPE NumTab IS TABLE OF employees.employee_id%TYPE;TYPE NameTab IS TABLE OF employees.last_name%TYPE;enums NumTab;names NameTab;PROCEDURE print_first_n (n POSITIVE) ISBEGINIF enums.COUNT = 0 THENDBMS_OUTPUT.PUT_LINE ('Collections are empty.');ELSEDBMS_OUTPUT.PUT_LINE ('First ' || n || ' employees:');FOR i IN 1 .. n LOOPDBMS_OUTPUT.PUT_LINE ('  Employee #' || enums(i) || ': ' || names(i));END LOOP;END IF;END;BEGINSELECT employee_id, last_nameBULK COLLECT INTO enums, namesFROM employeesORDER BY employee_id;print_first_n(3);print_first_n(6);
END;
/输出
First 3 employees:
Employee #100: King
Employee #101: Kochhar
Employee #102: De Haan
First 6 employees:
Employee #100: King
Employee #101: Kochhar
Employee #102: De Haan
Employee #103: Hunold
Employee #104: Ernst
Employee #105: Austin
DECLARECURSOR c1 ISSELECT first_name, last_name, hire_dateFROM employees;TYPE NameSet IS TABLE OF c1%ROWTYPE;stock_managers  NameSet;  -- nested table of recordsBEGIN -- Assign values to nested table of records:SELECT first_name, last_name, hire_dateBULK COLLECT INTO stock_managersFROM employeesWHERE job_id = 'ST_MAN'ORDER BY hire_date;-- Print nested table of records:FOR i IN stock_managers.FIRST .. stock_managers.LAST LOOPDBMS_OUTPUT.PUT_LINE (stock_managers(i).hire_date || ' ' ||stock_managers(i).last_name  || ', ' ||stock_managers(i).first_name);END LOOP;END;
/结果
01-MAY-03 Kaufling, Payam
18-JUL-04 Weiss, Matthew
10-APR-05 Fripp, Adam
10-OCT-05 Vollman, Shanta
16-NOV-07 Mourgos, Kevin

下面这段代码是,输出数组中大于输入值i的数。

CREATE OR REPLACE TYPE numbers_type ISTABLE OF INTEGER
/
CREATE OR REPLACE PROCEDURE p (i IN INTEGER) AUTHID DEFINER ISnumbers1  numbers_type := numbers_type(1,2,3,4,5);
BEGINDBMS_OUTPUT.PUT_LINE('Before SELECT statement');DBMS_OUTPUT.PUT_LINE('numbers1.COUNT() = ' || numbers1.COUNT());FOR j IN 1..numbers1.COUNT() LOOPDBMS_OUTPUT.PUT_LINE('numbers1(' || j || ') = ' || numbers1(j));END LOOP;--Self-selecting BULK COLLECT INTO clause:SELECT a.COLUMN_VALUEBULK COLLECT INTO numbers1FROM TABLE(numbers1) aWHERE a.COLUMN_VALUE > p.iORDER BY a.COLUMN_VALUE;DBMS_OUTPUT.PUT_LINE('After SELECT statement');DBMS_OUTPUT.PUT_LINE('numbers1.COUNT() = ' || numbers1.COUNT());
END p;
/

上面这段代码是错误的,因为你从数组numbers1里面选,又插入到里面,结果就是里面什么也没有。
有两种解决办法,一是用游标存储,而是用新数组存储。第二种方法要比第一种快。
1.

CREATE OR REPLACE TYPE numbers_type ISTABLE OF INTEGER
/
CREATE OR REPLACE PROCEDURE p (i IN INTEGER) AUTHID DEFINER ISnumbers1  numbers_type := numbers_type(1,2,3,4,5);CURSOR c ISSELECT a.COLUMN_VALUEFROM TABLE(numbers1) aWHERE a.COLUMN_VALUE > p.iORDER BY a.COLUMN_VALUE;BEGINDBMS_OUTPUT.PUT_LINE('Before FETCH statement');DBMS_OUTPUT.PUT_LINE('numbers1.COUNT() = ' || numbers1.COUNT());FOR j IN 1..numbers1.COUNT() LOOPDBMS_OUTPUT.PUT_LINE('numbers1(' || j || ') = ' || numbers1(j));END LOOP;OPEN c;FETCH c BULK COLLECT INTO numbers1;CLOSE c;DBMS_OUTPUT.PUT_LINE('After FETCH statement');DBMS_OUTPUT.PUT_LINE('numbers1.COUNT() = ' || numbers1.COUNT());IF numbers1.COUNT() > 0 THENFOR j IN 1..numbers1.COUNT() LOOPDBMS_OUTPUT.PUT_LINE('numbers1(' || j || ') = ' || numbers1(j));END LOOP;END IF;
END p;
/
CREATE OR REPLACE TYPE numbers_type ISTABLE OF INTEGER
/
CREATE OR REPLACE PROCEDURE p (i IN INTEGER) AUTHID DEFINER ISnumbers1  numbers_type := numbers_type(1,2,3,4,5);numbers2  numbers_type := numbers_type(0,0,0,0,0);BEGINDBMS_OUTPUT.PUT_LINE('Before SELECT statement');DBMS_OUTPUT.PUT_LINE('numbers1.COUNT() = ' || numbers1.COUNT());FOR j IN 1..numbers1.COUNT() LOOPDBMS_OUTPUT.PUT_LINE('numbers1(' || j || ') = ' || numbers1(j));END LOOP;DBMS_OUTPUT.PUT_LINE('numbers2.COUNT() = ' || numbers2.COUNT());FOR j IN 1..numbers2.COUNT() LOOPDBMS_OUTPUT.PUT_LINE('numbers2(' || j || ') = ' || numbers2(j));END LOOP;SELECT a.COLUMN_VALUEBULK COLLECT INTO numbers2      -- numbers2 appears hereFROM TABLE(numbers1) a        -- numbers1 appears hereWHERE a.COLUMN_VALUE > p.iORDER BY a.COLUMN_VALUE;DBMS_OUTPUT.PUT_LINE('After SELECT statement');DBMS_OUTPUT.PUT_LINE('numbers1.COUNT() = ' || numbers1.COUNT());IF numbers1.COUNT() > 0 THENFOR j IN 1..numbers1.COUNT() LOOPDBMS_OUTPUT.PUT_LINE('numbers1(' || j || ') = ' || numbers1(j));END LOOP;END IF;DBMS_OUTPUT.PUT_LINE('numbers2.COUNT() = ' || numbers2.COUNT());IF numbers2.COUNT() > 0 THENFOR j IN 1..numbers2.COUNT() LOOPDBMS_OUTPUT.PUT_LINE('numbers2(' || j || ') = ' || numbers2(j));END LOOP;END IF;
END p;
/

用在fetch 里面

用在 returning into clause里

参考自:https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/plsql-optimization-and-tuning.html#GUID-19F50644-C88E-49AF-B31C-3EE4B4432714

oracle bulk collect相关推荐

  1. oracle bulk collect into,BULK COLLECT INTO

    下面我们来看两个范例,一个是使用BULK COLLECT的,一个没有: 范例1.使用多次循环来检索并显示数据. 范例2.一次性获取数据,然后再循环显示. 下面是一些有关BULK COLLECT的建议: ...

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

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

  3. Oracle 中使用 fetch bulk collect into 批量效率的读取

    http://www.jzxue.com/shujuku/oracle/201109/21-8976.html 通常我们获取游标数据是用 fetch some_cursor into var1, va ...

  4. Oracle 中使用 fetch bulk collect into 批量效率的读取游标数据

    通常我们获取游标数据是用 fetch some_cursor into var1, var2 的形式,当游标中的记录数不多时不打紧.然而自 Oracle 8i 起,Oracle 为我们提供了 fetc ...

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

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

  6. bulk怎么使用oracle,oracle学习之bulk collect用法

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

  7. oracle中bulk,Oracle数据库之FORALL与BULK COLLECT语句

    1 PL/SQL块的执行过程 当PL/SQL运行时引擎处理一块代码时,它使用PL/SQL引擎来执行过程化的代码,而将SQL语句发送给SQL引擎来执行: SQL引擎执行完毕后,将结果再返回给PL/SQL ...

  8. forall分批提交oracle,使用BULK COLLECT+FORALL加速批量提交

    一.批量提交 批量提交特点: 占用较少undo,资源(独占锁,undo)快速释放,执行时间长 批量提交适合场景: 在线大批量插入,更新,删除数据 二.BULK COLLECT+FORALL性能提升 1 ...

  9. oracle学习总结三(bulk collect用法)

    通过bulk collect减少loop处理的开销 发表人:logzgh | 发表时间: 2006年五月19日, 10:56 采用bulk collect可以将查询结果一次性地加载到collectio ...

最新文章

  1. SAP HUM 如何对一个HU做上架?
  2. 2017.10.8 软件工程----总体设计
  3. linux 操作系统详解,Linux操作系统详解
  4. 数学基础知识(高精、快速幂、龟速乘……)
  5. php识别中文编码并自动转换为UTF-8
  6. SQL:清空数据库所有数据
  7. 备份图解 ---mysql 博客
  8. python3 asyncio_asyncio--python3未来并发编程主流、充满野心的模块
  9. 异步处理函数async_Spring @Async异步处理注释
  10. java怎么设置zip的名词_[Java]对新创建Zip文件的子项设置 压缩/存储 模式
  11. android studio ndk 开发入门
  12. SQL语句:联合查询
  13. python变成灰色_Python怎么把彩色图像转换成灰色图像?
  14. 让gentoo安装不再难
  15. CAD图纸打印时如何去掉图纸边框的白边?
  16. IUSR_用户(Internet来宾账号)
  17. 关系型数据库与非关系型数据库详细比较
  18. 企业年会直播该怎么玩
  19. ABAP 获取批次特性
  20. 光的单位-坎德拉,光通量,照度,尼特

热门文章

  1. 2020薪资排名第一的专业公布,除了计算机还有这些!
  2. 链表问题5——反转部分单向链表
  3. Classifying dynamic textures via spatiotemporal fractal analysis(许教授)
  4. IEEE signal processing letters 投稿经验
  5. Xcode10:Implicit declaration of function '' is invalid in C99
  6. Car-eye-http-flv-module 实现nginx-rtmp-mudule HTTP方式的FLV直播功能
  7. struts1-2,springMVC原理基本对比(单例,多例)-servlet与filter区别
  8. Java 容器 泛型:一、认识容器
  9. 建筑物占据的网格数目的确定(三)
  10. (转)Unity Assets目录下的特殊文件夹名称(作用和是否会被打包到build中)