Oracle 的 bulk collect 和 forall 用法

FORALL语句的一个关键性改进,它可大大简化代码,并且对于那些要在PL/SQL程序中更新很多行数据的程序来说,它可显著提高其性能。

1:
用FORALL来增强DML的处理能力
Oracle为Oracle8i中的PL/SQL引入了两个新的数据操纵语言(DML)语句:BULK COLLECT和FORALL。这两个语句在PL/SQL内部进行一种数组处理

;BULK COLLECT提供对数据的高速检索,FORALL可大大改进INSERT、UPDATE和DELETE操作的性能。Oracle数据库使用这些语句大大减少了

PL/SQL与SQL语句执行引擎的环境切换次数,从而使其性能有了显著提高。


使用BULK COLLECT,你可以将多个行引入一个或多个集合中,而不是单独变量或记录中。下面这个BULK COLLECT的实例是将标题中包含

有"PL/SQL"的所有书籍检索出来并置于记录的一个关联数组中,它们都位于通向该数据库的单一通道中。
DECLARE
   TYPE books_aat

      IS TABLE OF book%ROWTYPE 
      INDEX BY PLS_INTEGER;
   books books_aat;
BEGIN
   SELECT *
     BULK COLLECT INTO book
     FROM books
    WHERE title LIKE '%PL/SQL%';
   ...
END;


类似地,FORALL将数据从一个PL/SQL集合传送给指定的使用集合的表。下面的代码实例给出一个过程,即接收书籍信息的一个嵌套表,并将该

集合(绑定数组)的全部内容插入该书籍表中。注意,这个例子还利用了Oracle9i的FORALL的增强功能,可以将一条记录直接插入到表中。

BULK COLLECT和FORALL都非常有用,它们不仅提高了性能,而且还简化了为PL/SQL中的SQL操作所编写的代码。下面的多行FORALL INSERT相当

清楚地说明了为什么PL/SQL被认为是Oracle数据库的最佳编程语言。
CREATE TYPE books_nt 
IS TABLE OF book%ROWTYPE; 
/
CREATE OR REPLACE PROCEDURE add_books (

books_in IN books_nt)
IS
BEGIN
FORALL book_index 
    IN books_in.FIRST .. books_in.LAST
    INSERT INTO book 
       VALUES books_in(book_index);
   ...
END;


不过在Oracle数据库10g之前,以FORAll方式使用集合有一个重要的限制:该数据库从IN范围子句中的第一行到最后一行,依次读取集合的内容

。如果在该范围内遇到一个未定义的行,Oracle数据库将引发ORA-22160异常事件:


ORA-22160: element at index [N] does not exist


对于FORALL的简单应用,这一规则不会引起任何麻烦。但是,如果想尽可能地充分利用FORALL,那么要求任意FORALL驱动数组都要依次填充可

能会增加程序的复杂性并降低性能。

在Oracle数据库10g中,PL/SQL现在在FORALL语句中提供了两个新子句:INDICES OF与VALUES OF,它们使你能够仔细选择驱动数组中该由扩展

DML语句来处理的行。
当绑定数组为稀疏数组或者包含有间隙时,INDICES OF会非常有用。该语句的语法结构为: 
FORALL indx IN INDICES 
OF sparse_collection 

INSERT INTO my_table VALUES sparse_collection (indx);

VALUES OF 与 INDICES OF 的区别就是直接取集合的值,而不用通过index去取值该语句的语法结构为: 

FORALL value IN VALUES OF sparse_collection 
INSERT INTO my_table VALUES value;

你可能感兴趣的:(oracle,forall,collect,bulk)