3.2改写后的存储过程(基于9i)
现在,笔者使用批量绑定的方式,也就是使用BULK COLLECT和FORALL的方式来改写上面的存储过程:P_HANDLE_PIX。
CREATE OR REPLACE PROCEDURE P_HANDLE_PIX_NEW(
ai_rtd out number,
as_rmsg out varchar2)
IS
TYPEt_pixid IS TABLE OF pix_trans.id%TYPE INDEX BY PLS_INTEGER;
TYPEt_pixtype IS TABLE OF pix_trans.pixtype%TYPE INDEX BY PLS_INTEGER;
TYPEt_actcode IS TABLE OF pix_trans.actcode%TYPE INDEX BY PLS_INTEGER;
![]()
pix_id t_pixid;
pix_pixtype t_pixtype;
pix_actcode t_actcode;
![]()
succ_pix_id t_pixid;
succ_pix_pixtype t_pixtype;
succ_pix_actcode t_actcode;
![]()
fail_pix_id t_pixid;
![]()
ll_begin number;
ll_end number;
![]()
indx_succ number;
indx_fail number;
BEGIN
SELECT to_char(sysdate,'sssss') INTO ll_begin FROM dual;
--获得所有的pix记录
SELECT id,pixtype,actcode
BULK COLLECT INTO pix_id,pix_pixtype,pix_actcode
FROM pix_trans
WHERE status = '00';
--如果集合为空,则退出
IF pix_id.count=0 THEN
ai_rtd := 0;
as_rmsg := 'No recoreds';
RETURN;
END IF;
--逐条处理记录
indx_succ := 1;
indx_fail := 1;
FOR indx IN pix_id.first .. pix_id.last
LOOP
P_HANDLE_SOTCK(pix_id(indx),pix_pixtype(indx),pix_actcode(indx),ai_rtd,as_rmsg);
IF ai_rtd>0 THEN
succ_pix_id(indx_succ) := pix_id(indx);
succ_pix_pixtype(indx_succ) := pix_pixtype(indx);
succ_pix_actcode(indx_succ) := pix_actcode(indx);
indx_succ := indx_succ + 1;
ELSE
fail_pix_id(indx_fail) := pix_id(indx);
indx_fail := indx_fail + 1;
END IF;
END LOOP;
--将处理成功的记录插入历史表
FORALL indx IN succ_pix_id.first .. succ_pix_id.last
INSERT INTO pix_trans_his(id,pixtype,actcode)
VALUES (succ_pix_id(indx),succ_pix_pixtype(indx),succ_pix_actcode(indx));
![]()
--更新记录的成功标志
FORALL indx IN succ_pix_id.first .. succ_pix_id.last
UPDATE pix_trans SET status = '10' WHERE id = succ_pix_id(indx);
![]()
--更新记录的失败标志
FORALL indx IN fail_pix_id.first .. fail_pix_id.last
UPDATE pix_trans SET status = '10' WHERE id = fail_pix_id(indx);
![]()
SELECT to_char(sysdate,'sssss') INTO ll_end FROM dual;
DBMS_OUTPUT.PUT_LINE('forall:' || to_char(ll_end - ll_begin));
END;
我们看到,使用批量绑定的后果就是程序的可读性差了,程序代码更加复杂了。我们可以再次进行测试,看看改写后运行一次需要多长时间。
SQL> set serveroutput on;
SQL> declare
2li_rtd number;
3ls_rmsg varchar2(255);
4begin
5p_handle_pix_new(li_rtd,ls_rmsg);
6end;
7/
for loop:11
![]()
PL/SQL procedure successfully completed.
可以看到现在运行一次只需要11秒。时间相比不使用批量绑定来说,缩短了9秒,也就是大约提高了45%的性能。这应该算是一个很惊人的数字了。还有没有办法改进呢?我们试试10g下是不是还可以更快。
