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秒。