-2

我有一个新问题必须解决!我创建了一个表作为类型

TYPE ebRBKTable IS TABLE OF EBTDCCRBK%ROWTYPE INDEX BY PLS_INTEGER;
rbkTable        ebRBKTable;

然后通过以下语句将一些数据插入表中

rbkTable(InsertTable).BDADDUSERID             := 'FT_RBK_TDCC';

最后我用以下语句插入

FORALL i IN 1..InsertTable - 1
INSERT INTO EBTDCCRBK VALUES rbaTable(i);

我想问一下是否有一些方法可以一次性插入所有类型count(i)

谢谢!

4

1 回答 1

1

语句本身不是forall循环。

它的作用是将数组的所有元素一次性发送到 SQL 引擎,这使 SQL 能够插入行,而无需返回 PL/SQL 引擎来获取更多数据。

换句话说FORALL,删除了常规 FOR 循环中的上下文切换。

我们可以用一个简单的跟踪来证明这一点。考虑:

SQL> alter session set sql_trace=true;

Session altered.

SQL> declare
  2    TYPE ebRBKTable IS TABLE OF EBTDCCRBK%ROWTYPE INDEX BY PLS_INTEGER;
  3    rbkTable        ebRBKTable;
  4  begin
  5
  6    for idx in 1..100000
  7    loop
  8      rbkTable(idx).BDADDUSERID := dbms_random.string('a', 10);
  9    end loop;
 10
 11    forall idx in 1..rbkTable.count
 12    insert into EBTDCCRBK values rbkTable(idx);
 13    commit;
 14
 15  end;
 16  /

在我们看到的 SQL 跟踪中:

INSERT INTO EBTDCCRBK
VALUES
 (:B1 )


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.07       0.07          1        724       3066      100000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.07       0.07          1        724       3066      100000

与正则循环:

SQL> alter session set sql_trace=true;

Session altered.

SQL> declare
  2    TYPE ebRBKTable IS TABLE OF EBTDCCRBK%ROWTYPE INDEX BY PLS_INTEGER;
  3    rbkTable        ebRBKTable;
  4  begin
  5
  6    for idx in 1..100000
  7    loop
  8      rbkTable(idx).BDADDUSERID := dbms_random.string('a', 10);
  9    end loop;
 10
 11    for idx in 1..rbkTable.count
 12    loop
 13      insert into EBTDCCRBK values rbkTable(idx);
 14    end loop;
 15    commit;
 16
 17  end;
 18  /

PL/SQL procedure successfully completed.

SQL> alter session set sql_trace=false;

跟踪文件显示:

INSERT INTO EBTDCCRBK
VALUES
 (:B1 )


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute 100000      3.33       3.24          1        689     104216      100000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total   100001      3.33       3.24          1        689     104216      100000

请注意,该FORALL版本中的跟踪文件只执行了一次,即 SQL 引擎一键完成了工作。在FOR LOOP变体中,SQL 引擎有 100k 次执行,并使用更多 CPU 来完成相同的工作(因为它必须执行大量单个操作,并且会话是从 pl/sql->sql 为每个插入的行进行上下文切换.

于 2013-03-26T11:25:09.310 回答