软件开发数据库

db2 存储过程continue的问题

CREATE PROCEDURE DMINST.PROC_IDS_CUSTACC (IN IN_WORK_DATE CHARACTER(8), IN IN_LAST_DATE CHARACTER(8), IN IN_Y_DAYS INTEGER, IN IN_J_DAYS INTEGER, IN IN_N_DAYS INTEGER ) LANGUAGE SQL NOT DETERMINISTIC CALLED ON NULL INPUT MODIFIES SQL DATA INHERIT SPECIAL R...显示全部
CREATE PROCEDURE DMINST.PROC_IDS_CUSTACC
(IN IN_WORK_DATE CHARACTER(8), 
IN IN_LAST_DATE CHARACTER(8), 
IN IN_Y_DAYS INTEGER, 
IN IN_J_DAYS INTEGER, 
IN IN_N_DAYS INTEGER
) 
LANGUAGE SQL
NOT DETERMINISTIC
CALLED ON NULL INPUT
MODIFIES SQL DATA
INHERIT SPECIAL REGISTERS
BEGIN 
/*变量声明*/
DECLARE SQLCODE INT DEFAULT 0; --SQL返回代码
DECLARE SQLSTATE CHAR(5) DEFAULT '00000'; --SQL默认返回代码00000返回成功

--定义游标
DECLARE CUR CURSOR FOR select ACCT_NO,CUST_NO,CUR from 
(SELECT ACCT_NO,CUST_NO,CUR FROM DWINST.FDS_DEPAGR UNION SELECT LN_ACCT_NO as acct_no,CUST_NO ,CURR_COD as cur FROM DWINST.FDS_LNACCT) a 
where ACCT_NO='9927000041499004010006310';


/*错误声明处理 */
--警告处理
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' 
BEGIN
SELECT SQLCODE,SQLSTATE INTO V_SQLCODE, V_SQLSTATE FROM SYSIBM.SYSDUMMY1;
SET V_MSG = CHAR(V_SQLCODE)||V_SQLSTATE||'WARNING' ;
SET V_PROC_FLG=1;
SET V_PROC_SUCC_FLG=0;
SET V_PROC_STM=NULL;
SET V_PROC_ETM=NULL;
CALL DMINST.PROC_BAH_LOG(V_PROC_ID, V_PROC_NAME ,V_PROC_STM,V_PROC_ETM, V_PROC_FLG, V_PROC_SUCC_FLG, V_MSG);
END;

--出错处理,退出
DECLARE exit HANDLER FOR SQLEXCEPTION
BEGIN
SELECT SQLCODE,SQLSTATE INTO V_SQLCODE, V_SQLSTATE FROM SYSIBM.SYSDUMMY1;
SET V_MSG = CHAR(V_SQLCODE)||V_SQLSTATE||'ERROR' ;
SET V_PROC_FLG=2;
SET V_PROC_SUCC_FLG=1;
SET V_PROC_STM=NULL;
SET V_PROC_ETM=CURRENT TIMESTAMP;
ROLLBACK ;
CALL DMINST.PROC_BAH_LOG(V_PROC_ID, V_PROC_NAME ,V_PROC_STM,V_PROC_ETM, V_PROC_FLG, V_PROC_SUCC_FLG, V_MSG);

END;
/* 处理主程序开始 */

--打开游标
OPEN CUR;
FETCH_JG_LOOP: LOOP
FETCH CUR INTO V_ACCT_NO,V_CUST_NO,V_CUR_COD;
IF SQLCODE !=0 THEN
LEAVE FETCH_JG_LOOP;
END IF; 
--计算存款积数
SELECT CASE WHEN SUBSTR(V_WORK_DATE,7,2)='01' THEN A.AMT ELSE A.AMT+COALESCE(B.M_DEP_ACC,0) END,CASE WHEN SUBSTR(V_WORK_DATE,5,4) IN('0101','0401','0701','1001') THEN A.AMT ELSE A.AMT+COALESCE(B.Q_DEP_ACC,0) END,CASE WHEN SUBSTR(V_WORK_DATE,5,4)='0101' THEN A.AMT ELSE A.AMT+COALESCE(B.Y_DEP_ACC,0) END INTO V_M_DEP_ACC,V_Q_DEP_ACC,V_Y_DEP_ACC FROM DWINST.FDS_DEPAGR A LEFT JOIN DMINST.IDS_CUSTACC_FB B ON A.ACCT_NO=B.ACCT_NO AND A.CUR=B.CUR_COD AND B.DT=V_LAST_DATE WHERE A.ACCT_NO=V_ACCT_NO AND A.CUR=V_CUR_COD ;
if SQLSTATE='02000' then
return 1;
end if;
--计算存款日均
SET V_M_AVE_DEP=V_M_DEP_ACC/V_Y_DAYS;
SET V_Q_AVE_DEP=V_Q_DEP_ACC/V_J_DAYS;
SET V_Y_AVE_DEP=V_Y_DEP_ACC/V_N_DAYS;

--计算协定存款积数
SELECT CASE WHEN SUBSTR(V_WORK_DATE,7,2)='01' THEN A.AGR_AMT ELSE A.AGR_AMT+COALESCE(B.M_AGR_DEP_ACC,0) END,CASE WHEN SUBSTR(V_WORK_DATE,5,4) IN('0101','0401','0701','1001') THEN A.AGR_AMT ELSE A.AGR_AMT+COALESCE(B.Q_AGR_DEP_ACC,0) END,CASE WHEN SUBSTR(V_WORK_DATE,5,4)='0101' THEN A.AGR_AMT ELSE A.AGR_AMT+COALESCE(B.Y_AGR_DEP_ACC,0) END INTO V_M_AGR_DEP_ACC,V_Q_AGR_DEP_ACC,V_Y_AGR_DEP_ACC FROM DWINST.FDS_DEPAGR A LEFT JOIN DMINST.IDS_CUSTACC_FB B ON A.ACCT_NO=B.ACCT_NO AND A.CUR=B.CUR_COD AND B.DT=V_LAST_DATE WHERE A.ACCT_NO=V_ACCT_NO AND A.CUR=V_CUR_COD ;
if SQLSTATE='02000' then
return 2;
end if;
--计算协定存款日均
SET V_M_AGR_AVE_DEP=V_M_AGR_DEP_ACC/V_Y_DAYS;
SET V_Q_AGR_AVE_DEP=V_Q_AGR_DEP_ACC/V_J_DAYS;
SET V_Y_AGR_AVE_DEP=V_Y_AGR_DEP_ACC/V_N_DAYS;


--计算贷款积数
SELECT CASE WHEN SUBSTR(V_WORK_DATE,7,2)='01' THEN A.LN_BAL ELSE A.LN_BAL+COALESCE(B.M_LN_ACC,0) END,CASE WHEN SUBSTR(V_WORK_DATE,5,4) IN('0101','0401','0701','1001') THEN A.LN_BAL ELSE A.LN_BAL+COALESCE(B.Q_LN_ACC,0) END,CASE WHEN SUBSTR(V_WORK_DATE,5,4)='0101' THEN A.LN_BAL ELSE A.LN_BAL+COALESCE(B.Y_LN_ACC,0) END INTO V_M_LN_ACC,V_Q_LN_ACC,V_Y_LN_ACC FROM DWINST.FDS_LNACCT A LEFT JOIN DMINST.IDS_CUSTACC_FB B ON A.CURR_COD=B.CUR_COD AND A.LN_ACCT_NO=B.ACCT_NO AND B.DT=V_LAST_DATE WHERE A.LN_ACCT_NO=V_ACCT_NO AND A.CURR_COD=V_CUR_COD ;
if SQLSTATE='02000' then
return 3;
end if;
--计算贷款积数
SET V_M_AVE_LN=V_M_LN_ACC/V_Y_DAYS;
SET V_Q_AVE_LN=V_Q_LN_ACC/V_J_DAYS;
SET V_Y_AVE_LN=V_Y_LN_ACC/V_N_DAYS;


INSERT INTO DMINST.IDS_CUSTACC(ACCT_NO,CUST_NO,CUR_COD,M_DEP_ACC,Q_DEP_ACC,Y_DEP_ACC,M_AVE_DEP,Q_AVE_DEP,Y_AVE_DEP,M_AGR_DEP_ACC,Q_AGR_DEP_ACC,Y_AGR_DEP_ACC,M_AGR_AVE_DEP,Q_AGR_AVE_DEP,Y_AGR_AVE_DEP,M_LN_ACC,Q_LN_ACC,Y_LN_ACC,M_AVE_LN,Q_AVE_LN,Y_AVE_LN) VALUES(V_ACCT_NO,V_CUST_NO,V_CUR_COD,V_M_DEP_ACC,V_Q_DEP_ACC,V_Y_DEP_ACC,V_M_AVE_DEP,V_Q_AVE_DEP,V_Y_AVE_DEP,V_M_AGR_DEP_ACC,V_Q_AGR_DEP_ACC,V_Y_AGR_DEP_ACC,V_M_AGR_AVE_DEP,V_Q_AGR_AVE_DEP,V_Y_AGR_AVE_DEP,V_M_LN_ACC,V_Q_LN_ACC,V_Y_LN_ACC,V_M_AVE_LN,V_Q_AVE_LN,V_Y_AVE_LN);
if SQLSTATE='02000' then
return 4;
end if;
END LOOP FETCH_JG_LOOP; 
CLOSE CUR;




COMMIT;
END;

现在的问题是,在return 3那个地方捕捉到02000了,捕捉到之后继续执行,是死循环执行。。。。不断的往DMINST.IDS_CUSTACC这个表插数据,这是为什么呢?我定义的游标只能查出一条数。按理说插入一条数据就完了,可现在是无限往里插同样的一条数据,为什么会这样子?收起
参与10

查看其它 8 个回答daijiangbo的回答

daijiangbodaijiangbo项目经理山东众阳软件有限公司
回复 5# ninth


    /*错误声明处理 */
--警告处理
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'
BEGIN
SET at_end = 1;
SELECT SQLCODE,SQLSTATE INTO V_SQLCODE, V_SQLSTATE FROM SYSIBM.SYSDUMMY1;
SET V_MSG = CHAR(V_SQLCODE)||V_SQLSTATE||'WARNING' ;
SET V_PROC_FLG=1;
SET V_PROC_SUCC_FLG=0;
SET V_PROC_STM=NULL;
SET V_PROC_ETM=NULL;
CALL DMINST.PROC_BAH_LOG(V_PROC_ID, V_PROC_NAME ,V_PROC_STM,V_PROC_ETM, V_PROC_FLG, V_PROC_SUCC_FLG, V_MSG);
END;
假设不加SET at_end = 1这一句,他就会成死循环吗?DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'
这一句的原理是什么呀,为什么会死循环?
软件开发 · 2011-11-03
浏览539

回答者

daijiangbo
项目经理山东众阳软件有限公司
擅长领域: AIXUnix服务器

daijiangbo 最近回答过的问题

回答状态

  • 发布时间:2011-11-03
  • 关注会员:1 人
  • 回答浏览:539
  • X社区推广