3.案例说明
由于原来的存储过程因为涉及到了很多表,比较复杂,不便于读者做测试。所以我简化了该过程,但是意思是一样的。简单说来,就是创建一个接口表,取名为:pix_trans,再创建一个历史表。将数据插入该接口表。然后写一个存储过程,取出该表里的数据并逐条处理。
1)创建pix_trans
SQL> create table pix_trans(id number not null,pixtype varchar2(10),actcode
varchar2(10),status varchar2(2));
SQL> alter table pix_trans add constraint pk_pix_trans primary key(id);
SQL> create table pix_trans_his as select * from pix_trans where 1=2;
2)插入测试数据
SQL> execute dbms_random.seed(0);
SQL> insert into pix_trans select rownum,trunc(10*dbms_random.normal),
trunc(10*dbms_random.normal),'00' from dba_objects;
SQL> commit;
SQL> select count(*) from pix_trans;
COUNT(*)
----------
109564
可以看到,我们的测试表大概有10万多条数据。
3.1 原存储过程
CREATE OR REPLACE PROCEDURE P_HANDLE_PIX(
ai_rtd out number,
as_rmsg out varchar2)
IS
CURSOR pix_trans
IS
SELECT id,pixtype,actcode
FROM pix_trans
WHERE status='00';
ll_begin number;
ll_end number;
BEGIN
SELECT to_char(sysdate,'sssss') INTO ll_begin FROM dual;
--打开游标
FOR pix IN pix_trans
LOOP
--实际处理每条记录
P_HANDLE_STOCK(pix.id,pix.pixtype,pix.actcode,ai_rtd,as_rmsg);
IF ai_rtd>0 THEN--如果成功则插入历史表,并设置成功标记
UPDATE pix_trans SET status = '10' WHERE id = pix.id;
![]()
INSERT INTO pix_trans_his(id,pixtype,actcode)
VALUES (pix.id,pix.pixtype,pix.actcode);
ELSE--如果失败,则设置失败标记
UPDATE pix_trans SET status = '90' WHERE id = pix.id;
END IF;
END LOOP;
SELECT to_char(sysdate,'sssss') INTO ll_end FROM dual;
DBMS_OUTPUT.PUT_LINE('for loop:' || to_char(ll_end - ll_begin));
END;
这个存储过程的逻辑比较简单,其中,P_HANDLE_STOCK是实际商务逻辑的处理的过程,读者可以自己随便写,我这里写了一个测试的过程,简单的将pix_trans表的id被3除后余1则认为失败,否则成功。
CREATE OR REPLACE PROCEDURE P_HANDLE_STOCK(
ai_pixid in number,
as_pixtype in pix_trans.pixtype%type,
as_pixcode in pix_trans.actcode%type,
ai_rtd out number,
as_rmsg out varchar2
)
IS
BEGIN
IF mod(ai_pixid,3) = 1 THEN
ai_rtd := -1;
as_rmsg := 'test';
ELSE
ai_rtd := 1;
as_rmsg := 'done';
END IF;
END;
我们开始测试,看看运行一次P_HANDLE_PIX需要多长时间。
SQL> set serveroutput on;
SQL> declare
2li_rtd number;
3ls_rmsg varchar2(255);
4begin
5p_handle_pix(li_rtd,ls_rmsg);
6end;
7/
for loop:20
![]()
PL/SQL procedure successfully completed.
从结果看,运行一次需要20秒。
