将Oracle中的整个表类型插入到没有索引的数据库中

时间:2013-03-26 05:28:06

标签: oracle indexing

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

的表
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)

的情况下插入所有类型

谢谢!

1 个答案:

答案 0 :(得分: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

vs regluar loop:

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转换的上下文 - &gt ;每个插入行的sql。