问题描述
嗨,先生,
希望您一切顺利,并感谢您提供oracle支持,非常感谢您的努力。
目前,我在生产中遇到一个问题,因此无法在此处复制代码,但我在下面写了以供参考。
我有1个过程,其中数据插入正在处理多个表,当我调用prc 1记录插入表中有多个表与某些条件这个过程的单一调用运行更快或在几秒钟内,我们可以说。但是我想称它为10万时间,因为我必须创建10万记录进行一些测试。
我正在使用循环调用prc,但是它非常慢,因为仅创建2k记录需要20分钟。打电话给中华人民共和国还有别的选择吗?
如下是逻辑,但实际上有很多验证块和多次插入
注意: 对于单个调用,它以秒为单位运行,但是在循环中调用2k次时,需要apprx 20分钟,并且在表中没有触发器
数组也存在,但未在上述过程中使用,仅用于调用引用
-- 添加了对象类型
希望您一切顺利,并感谢您提供oracle支持,非常感谢您的努力。
目前,我在生产中遇到一个问题,因此无法在此处复制代码,但我在下面写了以供参考。
我有1个过程,其中数据插入正在处理多个表,当我调用prc 1记录插入表中有多个表与某些条件这个过程的单一调用运行更快或在几秒钟内,我们可以说。但是我想称它为10万时间,因为我必须创建10万记录进行一些测试。
我正在使用循环调用prc,但是它非常慢,因为仅创建2k记录需要20分钟。打电话给中华人民共和国还有别的选择吗?
如下是逻辑,但实际上有很多验证块和多次插入
注意: 对于单个调用,它以秒为单位运行,但是在循环中调用2k次时,需要apprx 20分钟,并且在表中没有触发器
-------------------------------------------------------------------------------------------------
CREATE TABLE BLK_EMP
(
EMP_BATCH VARCHAR2(10 BYTE),
EMP_ID NUMBER,
E_RECID NUMBER,
DEPTNO NUMBER
);
/
create or replace TYPE e_address_obj AS OBJECT ( address VARCHAR2(50),
pincode NUMBER);
/
create or replace TYPE emp_addr_tab as table of e_address_obj;
/
create table t_rec
as
select (9876234+level) as eid
from dual
connect by level <= 300;
/
create sequence seq_emp_id;
/
--prc
create or replace package pkg_emp_addr
as
procedure prc_emp_addr(
in_batch_emp IN varchar
,in_empno IN NUMBER
,in_empaddr IN emp_addr_tab
,in_e_recid IN NUMBER
,in_out_deptno IN OUT NUMBER
);
end pkg_emp_addr;
/
create or replace PACKAGE BODY PKG_EMP_ADDR AS
procedure prc_emp_addr(
in_batch_emp IN varchar
,in_empno IN NUMBER
,in_empaddr IN emp_addr_tab
,in_e_recid IN NUMBER
,in_out_deptno IN OUT NUMBER
)
AS
L_DEPTNO NUMBER;
l_seq_emp_id number;
--l_table emp_addr_tab := emp_addr_tab();
BEGIN
L_DEPTNO := in_out_deptno;
IF L_DEPTNO IS NOT NULL
THEN
SELECT DEPTNO INTO in_out_deptno
FROM EMP
WHERE EMPNO = 7499;
ELSE
in_out_deptno := 101;
END IF;
l_seq_emp_id := seq_emp_id.nextval;
insert into blk_emp values(in_batch_emp, l_seq_emp_id, in_e_recid, in_out_deptno);
--commit;
exception
when others then
rollback;
raise_application_error(-20001,sqlerrm);
END prc_emp_addr;
END PKG_EMP_ADDR;
/
---calling it
declare
in_batch_emp varchar(2);
in_empno NUMBER;
in_out_deptno NUMBER;
TYPE myarray IS TABLE OF number;
l_data myarray;
emp_add_t emp_addr_tab;
CURSOR r IS
SELECT eid
FROM t_rec;
begin
emp_add_t := emp_addr_tab();
emp_add_t.extend(3);
emp_add_t(1) := e_address_obj('usa',440022);
emp_add_t(2) := e_address_obj('ind',401122);
emp_add_t(3) := e_address_obj('germany',662200);
for a in 1..1000
loop
open r;
loop
fetch r bulk collect into l_data limit 100;
for i in 1..l_data.count
loop
for idx IN emp_add_t.FIRST .. emp_add_t.COUNT
LOOP
in_out_deptno := null;
PKG_EMP_ADDR.prc_emp_addr(
'c'
,0
,emp_add_t
,l_data(i)
,in_out_deptno
);
END LOOP;
end loop;
exit when r%notfound;
end loop;
close r;
end loop;
commit;
exception
when others then
raise_application_error(-20001,sqlerrm);
end;
/
数组也存在,但未在上述过程中使用,仅用于调用引用
-- 添加了对象类型
专家解答
你正在做一整堆单行操作 ....你想看看在布景中做事。数据库的工作原理 (最好) 与集合不与行。
对于exmaple,您可以在For-idx循环后的单个操作中完成所有emp_batch插入
对于exmaple,您可以在For-idx循环后的单个操作中完成所有emp_batch插入
SQL>
SQL> create or replace package pkg_emp_addr
2 as
3 type batch_list is table of blk_emp%rowtype
4 index by pls_integer;
5
6 g_batch_list batch_list;
7
8 procedure prc_emp_addr(
9 in_batch_emp IN varchar
10 ,in_empno IN NUMBER
11 ,in_empaddr IN emp_addr_tab
12 ,in_e_recid IN NUMBER
13 ,in_out_deptno IN OUT NUMBER
14 );
15
16 procedure batch_insert;
17 end pkg_emp_addr;
18 /
Package created.
SQL>
SQL> create or replace PACKAGE BODY PKG_EMP_ADDR AS
2 g_default_deptno int;
3
4 procedure prc_emp_addr(
5 in_batch_emp IN varchar
6 ,in_empno IN NUMBER
7 ,in_empaddr IN emp_addr_tab
8 ,in_e_recid IN NUMBER
9 ,in_out_deptno IN OUT NUMBER
10 )
11 AS
12
13 L_DEPTNO NUMBER;
14 l_seq_emp_id number;
15 --l_table emp_addr_tab := emp_addr_tab();
16 BEGIN
17
18 L_DEPTNO := in_out_deptno;
19
20 IF L_DEPTNO IS NOT NULL
21 THEN
22 in_out_deptno := g_default_deptno;
23 ELSE
24 in_out_deptno := 101;
25 END IF;
26
27
28 l_seq_emp_id := seq_emp_id.nextval;
29 g_batch_list(g_batch_list.count+1).EMP_BATCH := in_batch_emp;
30 g_batch_list(g_batch_list.count).EMP_ID := l_seq_emp_id;
31 g_batch_list(g_batch_list.count).E_RECID := in_e_recid;
32 g_batch_list(g_batch_list.count).DEPTNO:= in_out_deptno;
33
34 exception
35 when others then
36 rollback;
37 raise_application_error(-20001,sqlerrm);
38
39 END prc_emp_addr;
40
41 procedure batch_insert is
42 begin
43 forall i in 1 .. g_batch_list.count
44 insert into blk_emp values g_batch_list(i);
45 end;
46
47 begin
48 SELECT DEPTNO INTO g_default_deptno
49 FROM EMP
50 WHERE EMPNO = 7499;
51 END PKG_EMP_ADDR;
52 /
Package body created.
SQL>
SQL> ---calling it
SQL>
SQL> set serverout on
SQL> declare
2 in_batch_emp varchar(2);
3 in_empno NUMBER;
4 in_out_deptno NUMBER;
5 TYPE myarray IS TABLE OF number;
6 l_data myarray;
7 emp_add_t emp_addr_tab;
8 CURSOR r IS
9 SELECT eid
10 FROM t_rec;
11 begin
12
13 emp_add_t := emp_addr_tab();
14 emp_add_t.extend(3);
15 emp_add_t(1) := e_address_obj('usa',440022);
16 emp_add_t(2) := e_address_obj('ind',401122);
17 emp_add_t(3) := e_address_obj('germany',662200);
18
19 for a in 1..100 -- 1000
20 loop
21
22 open r;
23 loop
24 fetch r bulk collect into l_data limit 100;
25 for i in 1..l_data.count
26 loop
27 pkg_emp_addr.g_batch_list.delete;
28
29 for idx IN emp_add_t.FIRST .. emp_add_t.COUNT
30 LOOP
31 in_out_deptno := null;
32 PKG_EMP_ADDR.prc_emp_addr(
33 'c'
34 ,0
35 ,emp_add_t
36 ,l_data(i)
37 ,in_out_deptno
38 );
39 END LOOP;
40 PKG_EMP_ADDR.batch_insert;
41
42
43 end loop;
44 exit when r%notfound;
45 end loop;
46 close r;
47 end loop;
48
49 commit;
50 exception
51 when others then
52 raise_application_error(-20001,sqlerrm);
53 end;
54 /
PL/SQL procedure successfully completed.
SQL>
SQL>
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




