在db2存储过程中,使用for循环的时候,我发现总是执行一次就不在执行,也就是不循环,原代码是这么写的:
--查出所有的产品号
FOR cur as select fsetcode
from setlist
where fyear = p_year order by fsetcode
DO
--插入临时表数据
CALL sp_query_CIRC(char(cur.fsetcode),
Integer(pvar_i_date1),
Integer(pvar_i_date2),
P_ERRORCODE,
P_ERRORMSG);
if P_ERRORCODE <> 0 then
rollback;
else
commit
end if;
end for;
查了很多资料,发现是commit的问题,这个for循环在db2的存储过程中会隐式的调用游标,但是在执行commit的时候,会将游标关闭,那这样的话,自然不会循环 了,那如果非要在for循环里调用commit的话,自然不能用for循环了。我使用下面的方法解决了这个问题,定义一个with hold的游标,这种类型的游标不会在commit的时候,将游标关闭的。
如果需要用rollback,需要定义savepoint,然后回滚到指定的回滚点。
declare cur cursor with hold for select fsetcode from setlist where fyear = p_year order by fsetcode for update;
declare continue handler for not found
begin
set v_notfound = 1;
end;
--查出所有的产品号
open cur;
set v_notfound=0;
fetch cur into p_code;
while v_notfound=0
Do
--插入临时表数据
SAVEPOINT SP ON ROLLBACK RETAIN CURSORS;
CALL sp_query_stocks_detail_CIRC(RTRIM(cast(char(p_code) as varchar(10))),
Integer(pvar_i_date1),
Integer(pvar_i_date2),
P_ERRORCODE,
P_ERRORMSG);
if P_ERRORCODE <> 0 then
rollback TO SAVEPOINT SP;
else
commit;
end if;
fetch cur into p_code;
end while;
close cur;
这个游标需要显示的打开和关闭的,当游标中没有数据的时候,会将v_notfound的值置为1,那循环就完成了,就可以关闭游标了!