`

使用forall语句的bulk dml操作

阅读更多

oracle 8i或更高版本的forall语句中,oracle提供了非常有意义的dml增强特性。Forall告诉PL/SQL运行期引擎批量绑定一个或多个集合的所有元素到sql语句中,这个动作是在发送信息到sql引擎之前发生。

 

为什么批量dml 是非常有用的呢?因为在oracle数据库中,plsqlsql引擎是紧密联系的,尽管我们可以在oracle数据库中使用java 语言,但是在oracle中,使用plsql语言还是最佳选择。虽然plsqlsql引擎紧密联系,但是,这种联系是非必要的联系,当plsql运行期引擎发送一段过程化代码,它执行这段代码是在plsql引擎中,而非将代码传送到sql擎中去执行。在有需要的情况下,比如代码中有sql语句,在sql引擎中会执行sql代码,然后将信息返回给plsql引擎。

 

plsqlsql引擎之间的控制传输叫context switch(上下文转发)。在oracle 8i或更高版本,允许批量绑定多个context switch到一个context switch,这样可以提高性能。这个增强的功能是forall以及bulk collect的使用,也就是在同一时间只经过一个应用转发,批量将相同结构的sql 传输给sql引擎执行,减少了应用的转发,从而提高效率。

 

 

 

使用forall应该遵循的规则

1. forall体部必须是单个的dml语句(insert,update,delete),不能有多条dml语句或其他语句。

 

2. dml 语句必须引用集合元素(直接写个简单的没有引用集合元素的语句是错误的),按照在foall中的index_row变量划分索引。Index_rowscope仅在forall中有效,你不能在scope之外引用它,并且集合的内容范围必须在low_bound----àupper_bound范围之内。

 

3. 不可以申明一个变量来充当index_row的角色。它是plsql engine隐性申明的,类型是PLS_INTEGER类型。

 

4. lower and upper bounds针对被forall中的sql语句使用,必须是一个有效的连续的索引值。如果是稀疏性的,可能会导致下列错误:ORA-22160: element at index [3] does not exist

注意:oracle10g 之后提供了indices of values of来支持非连续性的集合。

 

5. DML 语句中,你不能引用集合的单个field,相反地,你仅能整体引用集合的行,不管集合的field 是标量还是复杂的对象类型,都是如此,否则报错. 

 

6. 集合的索引变量,在DML 语句中不能是表达式

 

下面是一些使用的例子和常见的错误:

--测试表1
drop table test1;
create table test1(id number(10),name varchar2(10));
insert into test1 values(1,'aa');
insert into test1 values(2,'bb');
commit;

--测试表2
drop table test2;
create table test2(id number(10),name varchar2(10));

--test1
declare
  type dr_type is table of test1%ROWTYPE index by binary_integer;
  dr_table dr_type;
begin
  select id, name BULK COLLECT into dr_table from test1;
  FORALL i IN dr_table.first .. dr_table.last
    insert into test2 values dr_table (i);
  --error statement
  --1.insert into test2 values(dr_table(i));报没有足够的值错误,此处外面不可以加括号,当有多个字段的时候,单个字段可以加括号
  --2.insert into test2 values(dr_table(i).id,dr_table(i).name);集合的field不可以在forall中使用,必须是整体使用
  --3.insert into test2 values dr_table(i+1);错误,不可以对索引变量进行运算
  --4.insert into test2 values dr_table(i);dbms_output.put_line(i);不正确,找不到i,因为forall中只能使用单条语句可以引用索引变量
end;
--非连续集合使用,采用indices of collection

drop table mynumtable;
create table mynumtable(id number(10));

--测试非连续的集合中使用forall
Declare
  type mylist_type is table of number index by binary_integer;
  mylist mylist_type;
begin
  mylist(1) := 2;
  mylist(3) := 3;
  mylist(4) := 6;
  --forall i in mylist.first .. mylist.last 错误:下标为[2]的元素不存在
  forall i in indices of mylist --i值集合的索引,和连续的区别只不过这里使用indices of
              collection,可以是非连续的集合, 10g以上
    insert into mynumtable (id) values (mylist(i));
end;
/

 

 

 

分享到:
评论

相关推荐

    浅谈PL/SQL批处理语句:BULK COLLECT与FORALL对优化做出的贡献

    FORALL 语句则是另一种批处理技术,主要用于执行DML操作。它可以一次对集合中的所有元素执行相同的操作,而不是循环遍历集合并逐个执行。例如,如果我们有一个包含多个部门ID的集合,可以一次性插入这些部门到表中,...

    JAVA 与 Sql学习笔记

    这篇学习笔记主要关注如何在Oracle数据库中使用PL/SQL的FORALL语句进行批量操作,以及如何利用批绑定(Bulk Binding)来提升性能。此外,笔记还涵盖了存储过程中的参数传递,特别是传入数组的方法,以及SQL优化的...

    PLSQL 语句优化

    2. **使用 FORALL 执行批量更新或插入**:FORALL 语句可以用于一次性执行多个 DML 操作。 - **示例**:`FORALL i IN 1..v_employees.COUNT UPDATE employees SET salary = salary * 1.1 WHERE employee_id = v_...

    Oracle Bulk Binds技术分析.pdf

    输入绑定则使用`FORALL`关键字,它指示PL/SQL引擎在发送SQL语句给SQL引擎执行前先进行批量绑定。这样,对于一组操作,只需要一次上下文切换,提高了执行速度。例如: ```sql FORALL i IN index_range INSERT INTO ...

    oracle下巧用bulk collect实现cursor批量fetch的sql语句

    2. 结合FORALL进行DML操作:如果需要对批量数据执行INSERT、UPDATE或DELETE操作,可以使用FORALL语句,它允许在单个事务中对集合内的所有行执行相同的操作,进一步提升效率。 3. 注意绑定变量的使用:在构建查询时,...

    PL-SQL用户指南与参考(译)

    描述如何使用`%BULK_EXCEPTIONS`属性来处理FORALL语句中出现的异常。 ##### 十四、利用BULKCOLLECTION子句为集合赋值 **1、从游标中批量取得数据的例子** 演示如何使用BULKCOLLECT子句从游标中一次性获取大量数据...

    PL_SQL用户指南与参考.doc

    PL/SQL与SQL紧密集成,可以直接在PL/SQL代码中使用SQL语句,使得数据操作更加便捷高效。 **2、面向对象的支持** 虽然PL/SQL本身不是一种完全的面向对象语言,但它通过包、游标等机制支持了一些面向对象的特性,如...

    PLSQL笔记(EFRIOO&GUOH)1.doc

    #### 7.13.5 在 FORALL 语句上使用 INDICES OF 子句 ```sql FORALL i IN INDICES OF v_employees INSERT INTO employees (employee_id) VALUES (v_employees(i)); ``` #### 7.13.6 在 FORALL 语句上使用 VALUES ...

    oracle性能

    `FORALL`与`BULK COLLECT`是PL/SQL中的两个关键字,它们一起用于在存储过程或函数中执行批量DML操作,如INSERT、UPDATE或DELETE。这种方式可以减少网络往返次数,大大提高执行效率。 2. **存储过程(Stored ...

    High Performance PL/SQL from Steven Feuerstein

    - **FORALL**:FORALL语句允许程序员一次对集合中的所有元素执行DML操作,从而避免了循环内的单个DML操作,显著提升了执行速度。 - **示例代码**: ```sql DECLARE TYPE EmpTab IS TABLE OF Emp%ROWTYPE INDEX ...

    PLSQL笔记整理

    - **FORALL语句**: - 在`INSERT`、`UPDATE`、`DELETE`语句上使用批量绑定。 - 在`FORALL`语句中使用部分集合元素。 - 使用`INDECS OF`子句。 - 使用`VALUES OF`子句。 - 使用`SQL%BULK_ROWCOUNT`属性。 - **...

    oracl个人笔记总结

    - 批量绑定变量(FORALL)用于处理大量数据,例如`FORALL i IN 1..x.COUNT DML`,`SQL%BULK_ROWCOUNT(i)`可获取批量操作每一步影响的行数。 9. **BULK COLLECT子句**:用于一次性收集多个行,常用于SELECT INTO、...

    oracle删除数据方法。

    - 使用 `FORALL` 循环,一次性执行删除操作,提高了删除效率。 - 每次循环结束后提交事务,确保数据一致性。 - 当游标没有更多数据时,跳出循环。 4. **异常处理**: ```sql EXCEPTION WHEN OTHERS THEN ...

    Oracle10g_PL_SQL_编程

    11. **游标聚合函数**:学习使用BULK COLLECT INTO和FORALL语句进行批量操作,提高处理大量数据时的效率。 通过这个Oracle 10g PL/SQL教程,开发者可以深入理解PL/SQL的精髓,从而更好地进行数据库应用开发,提升...

    pl_sql_编程实例

    7. **update_rows.sql**:可能包含批量更新多行数据的示例,可能利用了BULK COLLECT和FORALL语句提高性能。 8. **while_loop2.sql**:展示了WHILE循环的使用,这是PL/SQL中用于重复执行代码块直到特定条件不再满足...

    Oracle PL/SQL学习官方教材

    教材还会讲解如何使用BULK COLLECT和FORALL语句进行批量操作,提高效率。 6. **索引和视图**:学习如何创建和管理索引,优化查询性能,以及创建和使用视图来抽象数据库表的复杂性。 7. **包(Package)**:包是PL/...

    Ocacle加速查询的存储过程

    集合写法(飞机速度)是通过一次性处理多个行来加速数据操作,如BULK COLLECT INTO和FORALL语句。这种技术将查询时间缩短到0.22秒,极大地提高了处理大量数据的速度。 5. **直接路径插入**: 直接路径插入避免了...

Global site tag (gtag.js) - Google Analytics