3.3进一步改写存储过程(基于10g)
CREATE OR REPLACE PROCEDURE P_HANDLE_PIX_NEW_10(
ai_rtd out number,
as_rmsg out varchar2)
IS
TYPE t_pix_pointer IS TABLE OF PLS_INTEGER;
TYPE t_pixid IS TABLE OF pix_trans.id%TYPE INDEX BY PLS_INTEGER;
TYPE t_pixtype IS TABLE OF pix_trans.pixtype%TYPE INDEX BY PLS_INTEGER;
TYPE t_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_pix_pointer := t_pix_pointer();
fail_pix_id t_pix_pointer := t_pix_pointer();
![]()
ll_begin number;
ll_end 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;
--逐条处理记录
FOR indx IN pix_id.first .. pix_id.last
LOOP
P_HANDLE_STOCK(pix_id(indx),pix_pixtype(indx),pix_actcode(indx),ai_rtd,as_rmsg);
IF ai_rtd>0 THEN
succ_pix_id.extend;
succ_pix_id(succ_pix_id.last) := indx;
ELSE
fail_pix_id.extend;
fail_pix_id(fail_pix_id.last) := indx;
END IF;
END LOOP;
--将处理成功的记录插入历史表
FORALL indx IN VALUES OF succ_pix_id
INSERT INTO pix_trans_his(id,pixtype,actcode)
VALUES (pix_id(indx),pix_pixtype(indx),pix_actcode(indx));
![]()
--更新记录的成功标志
FORALL indx IN VALUES OF succ_pix_id
UPDATE pix_trans SET status = '10' WHERE id = pix_id(indx);
![]()
--更新记录的失败标志
FORALL indx IN VALUES OF fail_pix_id
UPDATE pix_trans SET status = '10' WHERE id = pix_id(indx);
![]()
SELECT to_char(sysdate,'sssss') INTO ll_end FROM dual;
DBMS_OUTPUT.PUT_LINE('forall values of:' || to_char(ll_end - ll_begin));
END;
在10g里,我们可以减少了两个集合,而只是引入一个失败的集合指针和一个成功的集合指针。通过失败的集合指针,我们可以找到失败的pix_trans.id,从而更新pix_trans表里对应的记录的状态;通过成功的集合指针,我们可以找到需要插入历史表的三个字段的值。
那么这样改写以后的效果如何呢?我们来测试一下运行速度。
SQL> set serveroutput on;
SQL> declare
2li_rtd number;
3ls_rmsg varchar2(255);
4begin
5p_handle_pix_new_10(li_rtd,ls_rmsg);
6end;
7/
forall values of:10
![]()
PL/SQL procedure successfully completed.
可以看到,相比9i下的写法,速度提高了1秒钟。大约是9%左右。效果并不是很明显。
