踩过的坑,分享出来,希望大家不要再去踩了
报错信息:
代码清单:
function sf_updateStatus(iBatchSerialno varchar2, iActFlag char , iRejectMemo varchar2)
return sys_refcursor is
cur sys_refcursor;
PRAGMA AUTONOMOUS_TRANSACTION;
vl_serialno tbatch.l_serialno%type;
vc_actFlag tbatch.c_payflag%type;
vc_rejectMemo tbatch.c_rejectMemo%type;
vc_cause varchar2(255);
begin
vl_serialno := trim(iBatchSerialno);
vc_actFlag := trim(iActFlag);
vc_rejectMemo := trim(iRejectMemo);
vc_cause := '';
if vl_serialno is null then
vc_cause := '批次号batchserialno不能为空!';
open cur for
select '1' status ,
vl_serialno batchserialno ,
vc_cause cause
from dual;
return cur;
end if;
if vc_actFlag is null then
vc_cause := 'TA处理失败,操作类型actflag不能为空!';
open cur for
select '1' status ,
vl_serialno batchserialno ,
vc_cause cause
from dual;
return (cur);
end if;
if vl_serialno is not null and vc_actFlag is not null then
update tbatch t set t.c_payflag = vc_actFlag ,t.c_rejectMemo = vc_rejectMemo where t.l_serialno = vl_serialno;
update tdetails t set t.c_payflag = vc_actFlag where t.l_bathserialno = vl_serialno;
vc_cause := '更新状态成功!';
open cur for
select '0' status ,
vl_serialno batchserialno ,
vc_cause cause
from dual;
return cur;
else
vc_cause := '发生未知错误!';
open cur for
select '1' status ,
vl_serialno batchserialno ,
vc_cause cause
from dual;
return cur;
end if;
commit;
exception when others then
rollback;
RAISE_APPLICATION_ERROR(-20000, '[sf_updateStatus]异常报错:'||chr(13)||sqlerrm, TRUE);
end sf_updateStatus;
可以看得出,该函数有三个分支,前两个分支都为必要的非空判断,第三个分支则是主要的逻辑处理,可能已经有人看出了问题所在;
那就是commit放在了最后,即if 分支的外面导致了该错误的发生,因为由于其他分支可能并不需要commit操作!
解决办法:将commit 放在if 分支里面,这样保证了其他分支逻辑的准确性,从而避免该问提的发生!