我们再来看一下pl/sql块的执行过程:当pl/sql运行时引擎处理一块代码时,它使用pl/sql引擎来执行过程化的代码,而将sql语句发送给
我们再来看一下pl/sql块的执行过程:当pl/sql运行时引擎处理一块代码时,它使用pl/sql引擎来执行过程化的代码,而将sql语句发送给sql引擎来执行;sql引擎执行完毕后,将结果再返回给pl/sql引擎。这种在pl/sql引擎和sql引擎之间的交互,称为上下文交换(context switch)。每发生一次交换,就会带来一定的额外开销。
forall,用于增强pl/sql引擎到sql引擎的交换。bulk collect,用于增强sql引擎到pl/sql引擎的交换。(前面我们已经介绍过了)1. forall介绍
使用forall,可以将多个dml批量发送给sql引擎来执行,最大限度地减少上下文交互所带来的开销。下面是 forall 的一个示意图:
语法:
1 forall index_name in 2     { lower_bound .. upper_bound index_collection5     }dml_statement; 
说明:
index_name:一个无需声明的标识符,作为集合下标使用。
lower_bound .. upper_bound:数字表达式,来指定一组连续有效的索引数字下限和上限。该表达式只需解析一次。
indices of collection_name:用于指向稀疏数组的实际下标。跳过没有赋值的元素,例如被 delete 的元素,null 也算值。
values of index_collection_name:把该集合中的值当作下标,且该集合值的类型只能是 pls_integer/binary_integer。
save exceptions:可选关键字,表示即使一些dml语句失败,直到forall loop执行完毕才抛出异常。可以使用sql%bulk_exceptions 查看异常信息。
dml_statement:静态语句,例如:update或者delete;或者动态(execute immediate)dml语句。
2. forall的使用
示例所使用表结构:
 tmp_tab(2   id number(5),3   name varchar2(50)4 ); 
示例1,使用forall批量插入、修改、删除数据:
type tb_table_type tmp_tab%rowtype index by  binary_integer; 5   tb_table tb_table_type;i in 1..100 loop 8tb_table(i).id:=i;i;10   end loop;..tb_table.  tmp_tab values tb_table(i);14 end;
type tb_table_type tmp_tab%rowtype index by binary_integer; 4   tb_table tb_table_type;i in 1..100 loop 7tb_table(i).id:=i;i; 9   end loop;tmp_tab t set row = tb_table(i) where t.id =tb_table(i).id;12 end;
type tb_table_type tmp_tab%rowtype index by binary_integer;  tb_table tb_table_type; ..10 looptb_table(i).id:=i;tb_table(i).name:i;end loop;forall i tmp_tab where id =tb_table(i).id; end; 示例2,使用indices of子句:
type demo_table_type tmp_tab%rowtype index by binary_integer; 3   demo_table demo_table_type;i in 1..10 loop 6demo_table(i).id:=i;i; 8   end loop;demo_table.delete(3);11   demo_table.delete(6);12   demo_table.delete(9);13   forall i in indices of  demo_tabletmp_tab values demo_table(i);15 end ;
示例3,使用values of子句:
type index_poniter_type  pls_integer; 3   index_poniter index_poniter_type;tmp_tab%rowtype index by binary_integer; 5   demo_table demo_table_type;index_poniter := index_poniter_type(1,3,5,7);..10 loop  9demo_table(i).id:=i;i;11   end loop; index_ponitertmp_tab values demo_table(i);14 end; 
3. forall注意事项
使用forall时,应该遵循如下规则:
4. bulk collect介绍
bulk collect子句会批量检索结果,即一次性将结果集绑定到一个集合变量中,并从sql引擎发送到pl/sql引擎。
通常可以在select into、fetch into以及returning into子句中使用bulk collect。下面逐一描述bulk collect在这几种情形下的用法。
5. bulk collect的使用
5.1 在select into中使用bulk collect
示例:
   
 
   