将Oracle中的整个表类型插入数据库而不使用索引
我有一个新问题必须解决!我已经创建了一个表作为类型将Oracle中的整个表类型插入数据库而不使用索引,oracle,indexing,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 INS
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)
谢谢 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
与regluar循环相比:
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为每个插入的行切换上下文。你说的“一次插入所有类型而不包含计数(i)”是什么意思?你没有“计数(i)”在您的示例代码中。您到底想实现什么?我想从我的insert语句中删除“I”,就像下面的语句“insert INTO EBTDCCRBK VALUES rbaTable;”,数据库逐个存储日期的当前方式,我希望将oracle中的表类型一次性放入数据库表中,并提交一次以减少事务处理您不能删除(I),它是FORALL语句所需的。FORALL在一个步骤中发送所有数据,并且您在它之后只提交一次。请记住,FORALL不是FOR循环!:)这不是一个真正的问题。它没有说明您的工作是否使用现有代码完成,也没有说明您希望实现的目标是否合理。感谢您的详细解释。请问这些数字的单位是多少?是毫秒还是秒?@Kun Yaowan时间(cpu/运行时间)是秒。