我们再来看一下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
示例: