纠结的并发动态游标问题
时间:2011-12-08
来源:互联网
今天在程序中使用动态游标(考虑到SP并发问题),于是将原有的简单动态游标加以处理,使得游标名称也动态执行,发现了新问题,很是纠结,如下:
SET @V_SQL_SUB = 'DECLARE CUR_SCR_SUB_'+@V_BTCH_EXAM_ID+' SCROLL CURSOR FOR '+CHAR(13)+
'SELECT DISTINCT T1.SUB_ID '+CHAR(13)+
'FROM EXAM.SCR_SGMNT_SET_CD T1 '+CHAR(13)+
'where T1.BTCH_EXAM_ID = '+ @V_BTCH_EXAM_ID+
' AND T1.SUB_ID<>-1'
PRINT '@V_SQL_SUB='+@V_SQL_SUB
EXEC (@V_SQL_SUB)
SET @V_END_TIME =GETDATE()
EXEC PUB_PLFM.USP_LOG_CHK_SQL_RUN @SP_ID,@SP_NM,@I_TRM_ID,@I_SCHL_ID,@V_STEP_ID, @V_STEP_DSC,NULL, @V_CRNT_TIME,@V_END_TIME,@@rowcount,NULL,@V_SQL_SUB,NULL
SET @V_TMP_SQL_CUR= 'OPEN CUR_SCR_SUB_'+@V_BTCH_EXAM_ID;
EXEC (@V_TMP_SQL_CUR)
PRINT '共计科目数='+CAST(@@cursor_Rows AS VARCHAR(10))
SET @V_TMP_SQL_CUR='CUR_SCR_SUB_'+@V_BTCH_EXAM_ID
---DECLARE @V_CUR CURSOR;
---SET @V_CUR = 'CUR_SCR_SUB_'+@V_BTCH_EXAM_ID;
SET @V_SUB_CNT = @@cursor_Rows ---获得科目数
IF (@V_SUB_CNT>0) --如果科目大于0,则进行条件判断SQL串组织
BEGIN
SET @i=0;
--FETCH NEXT FROM @V_TMP_SQL_CUR into @V_SUB_ID;
SET @V_TMP_SQL_CUR = 'FETCH NEXT FROM CUR_SCR_SUB_'+@V_BTCH_EXAM_ID +' into @V_SUB_ID '
----报错信息:(1 行受影响)
共计科目数=4
@V_TMP_SQL_CUR=FETCH NEXT FROM CUR_SCR_SUB_20111208140702884 into @V_SUB_ID
消息 137,级别 15,状态 2,第 1 行
Must declare the scalar variable "@V_SUB_ID". PRINT '@V_TMP_SQL_CUR='+@V_TMP_SQL_CUR
EXEC (@V_TMP_SQL_CUR)
WHILE @@FETCH_STATUS = 0
BEGIN
SET @i = @i+1;
IF @V_SET_SUB = ''
SET @V_SET_SUB = CAST(@V_SUB_ID AS nVARCHAR(20))
ELSE
SET @V_SET_SUB =@V_SET_SUB+ ','+CAST(@V_SUB_ID AS nVARCHAR(20))
PRINT '@V_SET_SUB='+@V_SET_SUB
PRINT '@i='+CAST(@i AS VARCHAR(2))
IF (@i = 1)
BEGIN
SET @V_SQL_STR = 'CASE WHEN SUB_ID = '+CAST(@V_SUB_ID AS VARCHAR(20))+' THEN '+CHAR(13)
SET @V_SQL_SGMNT_NM = @V_SQL_STR;
END
ELSE
BEGIN
SET @V_SQL_STR = @V_SQL_STR + 'WHEN SUB_ID = '+CAST(@V_SUB_ID AS VARCHAR(20))+' THEN '+CHAR(13)
SET @V_SQL_SGMNT_NM = @V_SQL_SGMNT_NM+ 'WHEN SUB_ID = '+CAST(@V_SUB_ID AS VARCHAR(20))+' THEN '+CHAR(13)
END
---======================================================================================
--定义分段游标
SET @V_STEP_ID = 10000130+@i;
SET @V_STEP_DSC = '建立分档游标';
SET @V_CRNT_TIME = GETDATE();
-----判断游标是否存在
SELECT @V_CUR_ST=CURSOR_STATUS('global','CUR_SCR_SGMNT_'+@V_BTCH_EXAM_ID)
IF @V_CUR_ST<>-3
BEGIN
SET @V_TMP_SQL_CUR= 'DEALLOCATE CUR_SCR_SGMNT_'+@V_BTCH_EXAM_ID;
EXEC (@V_TMP_SQL_CUR)
END
----定义单科成绩分段游标
SET @V_SQL_CUR= ' DECLARE CUR_SCR_SGMNT_'+@V_BTCH_EXAM_ID+' SCROLL CURSOR FOR '+
' SELECT T.SGMNT_ID,T.LWR_SCR,T.LWR_CNDTN '+
',T.LMT_SCR,T.LMT_CNDTN,T.SGMNT_NM '+
' FROM EXAM.SCR_SGMNT_SET_CD T '+
' WHERE T.BTCH_EXAM_ID = '+@V_BTCH_EXAM_ID +
' AND T.SUB_ID='+CAST(@V_SUB_ID AS VARCHAR(20))+
' ORDER BY SEQ_ID ASC ';
PRINT @V_SQL_CUR
EXEC (@V_SQL_CUR)
----记录SQL日志
SET @V_END_TIME =GETDATE()
EXEC PUB_PLFM.USP_LOG_CHK_SQL_RUN @SP_ID,@SP_NM,@I_TRM_ID,@I_SCHL_ID,@V_STEP_ID, @V_STEP_DSC,NULL, @V_CRNT_TIME,@V_END_TIME,@@rowcount,NULL,@V_SQL_CUR,NULL
SET @V_TMP_SQL_CUR='OPEN CUR_SCR_SGMNT_'+@V_BTCH_EXAM_ID;--打开游标
EXEC (@V_TMP_SQL_CUR);
SET @V_SGMNT_CNT = @@cursor_Rows ---获得分段数
--PRINT '@V_SGMNT_CNT='+CAST(@V_SGMNT_CNT AS VARCHAR(20));
SET @k=0;
SET @V_TMP_SQL_CUR='FETCH NEXT FROM CUR_SCR_SGMNT_'+@V_BTCH_EXAM_ID;
EXEC (@V_TMP_SQL_CUR);
-----------------------------------------------------------------------------------
WHILE (@@FETCH_STATUS = 0)
BEGIN
--FETCH NEXT FROM CUR_SCR_SGMNT into @V_SGMNT_ID,@LWR_SCR,@LWR_CNDTN,@LMT_SCR,@LMT_CNDTN,@V_SGMNT_NM;
SET @V_TMP_SQL_CUR='FETCH NEXT FROM CUR_SCR_SGMNT_'+@V_BTCH_EXAM_ID+' into @V_SGMNT_ID,@LWR_SCR,@LWR_CNDTN,@LMT_SCR,@LMT_CNDTN,@V_SGMNT_NM'
EXEC (@V_TMP_SQL_CUR);
SET @k = @k+1;
PRINT ' @k='+CAST(@k AS VARCHAR(2))
IF (@k = 1)
BEGIN
SET @V_SQL_STR = @V_SQL_STR+CHAR(13)+'( CASE '
SET @V_SQL_SGMNT_NM = @V_SQL_SGMNT_NM+CHAR(13)+'( CASE '
END
SET @V_SQL_STR =@V_SQL_STR+ ' WHEN T.SCR '+ @LWR_CNDTN +CAST(@LWR_SCR AS VARCHAR(20))+' AND T.SCR '+ @LMT_CNDTN + CAST(@LMT_SCR AS VARCHAR(20)) +' THEN '''+ @V_SGMNT_ID+'''' +CHAR(13)
SET @V_SQL_SGMNT_NM =@V_SQL_SGMNT_NM+ ' WHEN T.SCR '+ @LWR_CNDTN +CAST(@LWR_SCR AS VARCHAR(20))+' AND T.SCR '+ @LMT_CNDTN + CAST(@LMT_SCR AS VARCHAR(20)) +' THEN '''+ @V_SGMNT_NM+'''' +CHAR(13)
IF (@k=@V_SGMNT_CNT)
BEGIN
SET @V_SQL_STR = @V_SQL_STR +' ELSE NULL END )'
SET @V_SQL_SGMNT_NM =@V_SQL_SGMNT_NM+' ELSE NULL END )'
END
END;
---关闭成绩分档游标
--CLOSE CUR_SCR_SGMNT;
--DEALLOCATE CUR_SCR_SGMNT;
SET @V_TMP_SQL_CUR= 'CLOSE CUR_SCR_SGMNT_'+@V_BTCH_EXAM_ID
EXEC (@V_TMP_SQL_CUR)
SET @V_TMP_SQL_CUR= 'DEALLOCATE CUR_SCR_SGMNT)_'+@V_BTCH_EXAM_ID
EXEC (@V_TMP_SQL_CUR)
---======================================================================================
IF (@i=@V_SUB_CNT)
BEGIN
SET @V_SQL_STR = @V_SQL_STR +' ELSE NULL END SGMNT_ID '
SET @V_SQL_SGMNT_NM = @V_SQL_SGMNT_NM +' ELSE NULL END SGMNT_NM '
END
SET @V_TMP_SQL_CUR=' FETCH NEXT FROM CUR_SCR_SUB_'+@V_BTCH_EXAM_ID+' into @V_SUB_ID'
EXEC (@V_TMP_SQL_CUR)
END----结束分段循环
---关闭课程游标
--CLOSE CUR_SCR_SUB;
--DEALLOCATE CUR_SCR_SUB;
SET @V_TMP_SQL_CUR= 'CLOSE CUR_SCR_SUB_'+@V_BTCH_EXAM_ID
EXEC (@V_TMP_SQL_CUR)
SET @V_TMP_SQL_CUR= 'DEALLOCATE CUR_SCR_SUB_'+@V_BTCH_EXAM_ID
EXEC (@V_TMP_SQL_CUR)
看那位高人指点一下怎么处理。
(另外一个非嵌套循环的已经成功执行)
SET @V_SQL_SUB = 'DECLARE CUR_SCR_SUB_'+@V_BTCH_EXAM_ID+' SCROLL CURSOR FOR '+CHAR(13)+
'SELECT DISTINCT T1.SUB_ID '+CHAR(13)+
'FROM EXAM.SCR_SGMNT_SET_CD T1 '+CHAR(13)+
'where T1.BTCH_EXAM_ID = '+ @V_BTCH_EXAM_ID+
' AND T1.SUB_ID<>-1'
PRINT '@V_SQL_SUB='+@V_SQL_SUB
EXEC (@V_SQL_SUB)
SET @V_END_TIME =GETDATE()
EXEC PUB_PLFM.USP_LOG_CHK_SQL_RUN @SP_ID,@SP_NM,@I_TRM_ID,@I_SCHL_ID,@V_STEP_ID, @V_STEP_DSC,NULL, @V_CRNT_TIME,@V_END_TIME,@@rowcount,NULL,@V_SQL_SUB,NULL
SET @V_TMP_SQL_CUR= 'OPEN CUR_SCR_SUB_'+@V_BTCH_EXAM_ID;
EXEC (@V_TMP_SQL_CUR)
PRINT '共计科目数='+CAST(@@cursor_Rows AS VARCHAR(10))
SET @V_TMP_SQL_CUR='CUR_SCR_SUB_'+@V_BTCH_EXAM_ID
---DECLARE @V_CUR CURSOR;
---SET @V_CUR = 'CUR_SCR_SUB_'+@V_BTCH_EXAM_ID;
SET @V_SUB_CNT = @@cursor_Rows ---获得科目数
IF (@V_SUB_CNT>0) --如果科目大于0,则进行条件判断SQL串组织
BEGIN
SET @i=0;
--FETCH NEXT FROM @V_TMP_SQL_CUR into @V_SUB_ID;
SET @V_TMP_SQL_CUR = 'FETCH NEXT FROM CUR_SCR_SUB_'+@V_BTCH_EXAM_ID +' into @V_SUB_ID '
----报错信息:(1 行受影响)
共计科目数=4
@V_TMP_SQL_CUR=FETCH NEXT FROM CUR_SCR_SUB_20111208140702884 into @V_SUB_ID
消息 137,级别 15,状态 2,第 1 行
Must declare the scalar variable "@V_SUB_ID". PRINT '@V_TMP_SQL_CUR='+@V_TMP_SQL_CUR
EXEC (@V_TMP_SQL_CUR)
WHILE @@FETCH_STATUS = 0
BEGIN
SET @i = @i+1;
IF @V_SET_SUB = ''
SET @V_SET_SUB = CAST(@V_SUB_ID AS nVARCHAR(20))
ELSE
SET @V_SET_SUB =@V_SET_SUB+ ','+CAST(@V_SUB_ID AS nVARCHAR(20))
PRINT '@V_SET_SUB='+@V_SET_SUB
PRINT '@i='+CAST(@i AS VARCHAR(2))
IF (@i = 1)
BEGIN
SET @V_SQL_STR = 'CASE WHEN SUB_ID = '+CAST(@V_SUB_ID AS VARCHAR(20))+' THEN '+CHAR(13)
SET @V_SQL_SGMNT_NM = @V_SQL_STR;
END
ELSE
BEGIN
SET @V_SQL_STR = @V_SQL_STR + 'WHEN SUB_ID = '+CAST(@V_SUB_ID AS VARCHAR(20))+' THEN '+CHAR(13)
SET @V_SQL_SGMNT_NM = @V_SQL_SGMNT_NM+ 'WHEN SUB_ID = '+CAST(@V_SUB_ID AS VARCHAR(20))+' THEN '+CHAR(13)
END
---======================================================================================
--定义分段游标
SET @V_STEP_ID = 10000130+@i;
SET @V_STEP_DSC = '建立分档游标';
SET @V_CRNT_TIME = GETDATE();
-----判断游标是否存在
SELECT @V_CUR_ST=CURSOR_STATUS('global','CUR_SCR_SGMNT_'+@V_BTCH_EXAM_ID)
IF @V_CUR_ST<>-3
BEGIN
SET @V_TMP_SQL_CUR= 'DEALLOCATE CUR_SCR_SGMNT_'+@V_BTCH_EXAM_ID;
EXEC (@V_TMP_SQL_CUR)
END
----定义单科成绩分段游标
SET @V_SQL_CUR= ' DECLARE CUR_SCR_SGMNT_'+@V_BTCH_EXAM_ID+' SCROLL CURSOR FOR '+
' SELECT T.SGMNT_ID,T.LWR_SCR,T.LWR_CNDTN '+
',T.LMT_SCR,T.LMT_CNDTN,T.SGMNT_NM '+
' FROM EXAM.SCR_SGMNT_SET_CD T '+
' WHERE T.BTCH_EXAM_ID = '+@V_BTCH_EXAM_ID +
' AND T.SUB_ID='+CAST(@V_SUB_ID AS VARCHAR(20))+
' ORDER BY SEQ_ID ASC ';
PRINT @V_SQL_CUR
EXEC (@V_SQL_CUR)
----记录SQL日志
SET @V_END_TIME =GETDATE()
EXEC PUB_PLFM.USP_LOG_CHK_SQL_RUN @SP_ID,@SP_NM,@I_TRM_ID,@I_SCHL_ID,@V_STEP_ID, @V_STEP_DSC,NULL, @V_CRNT_TIME,@V_END_TIME,@@rowcount,NULL,@V_SQL_CUR,NULL
SET @V_TMP_SQL_CUR='OPEN CUR_SCR_SGMNT_'+@V_BTCH_EXAM_ID;--打开游标
EXEC (@V_TMP_SQL_CUR);
SET @V_SGMNT_CNT = @@cursor_Rows ---获得分段数
--PRINT '@V_SGMNT_CNT='+CAST(@V_SGMNT_CNT AS VARCHAR(20));
SET @k=0;
SET @V_TMP_SQL_CUR='FETCH NEXT FROM CUR_SCR_SGMNT_'+@V_BTCH_EXAM_ID;
EXEC (@V_TMP_SQL_CUR);
-----------------------------------------------------------------------------------
WHILE (@@FETCH_STATUS = 0)
BEGIN
--FETCH NEXT FROM CUR_SCR_SGMNT into @V_SGMNT_ID,@LWR_SCR,@LWR_CNDTN,@LMT_SCR,@LMT_CNDTN,@V_SGMNT_NM;
SET @V_TMP_SQL_CUR='FETCH NEXT FROM CUR_SCR_SGMNT_'+@V_BTCH_EXAM_ID+' into @V_SGMNT_ID,@LWR_SCR,@LWR_CNDTN,@LMT_SCR,@LMT_CNDTN,@V_SGMNT_NM'
EXEC (@V_TMP_SQL_CUR);
SET @k = @k+1;
PRINT ' @k='+CAST(@k AS VARCHAR(2))
IF (@k = 1)
BEGIN
SET @V_SQL_STR = @V_SQL_STR+CHAR(13)+'( CASE '
SET @V_SQL_SGMNT_NM = @V_SQL_SGMNT_NM+CHAR(13)+'( CASE '
END
SET @V_SQL_STR =@V_SQL_STR+ ' WHEN T.SCR '+ @LWR_CNDTN +CAST(@LWR_SCR AS VARCHAR(20))+' AND T.SCR '+ @LMT_CNDTN + CAST(@LMT_SCR AS VARCHAR(20)) +' THEN '''+ @V_SGMNT_ID+'''' +CHAR(13)
SET @V_SQL_SGMNT_NM =@V_SQL_SGMNT_NM+ ' WHEN T.SCR '+ @LWR_CNDTN +CAST(@LWR_SCR AS VARCHAR(20))+' AND T.SCR '+ @LMT_CNDTN + CAST(@LMT_SCR AS VARCHAR(20)) +' THEN '''+ @V_SGMNT_NM+'''' +CHAR(13)
IF (@k=@V_SGMNT_CNT)
BEGIN
SET @V_SQL_STR = @V_SQL_STR +' ELSE NULL END )'
SET @V_SQL_SGMNT_NM =@V_SQL_SGMNT_NM+' ELSE NULL END )'
END
END;
---关闭成绩分档游标
--CLOSE CUR_SCR_SGMNT;
--DEALLOCATE CUR_SCR_SGMNT;
SET @V_TMP_SQL_CUR= 'CLOSE CUR_SCR_SGMNT_'+@V_BTCH_EXAM_ID
EXEC (@V_TMP_SQL_CUR)
SET @V_TMP_SQL_CUR= 'DEALLOCATE CUR_SCR_SGMNT)_'+@V_BTCH_EXAM_ID
EXEC (@V_TMP_SQL_CUR)
---======================================================================================
IF (@i=@V_SUB_CNT)
BEGIN
SET @V_SQL_STR = @V_SQL_STR +' ELSE NULL END SGMNT_ID '
SET @V_SQL_SGMNT_NM = @V_SQL_SGMNT_NM +' ELSE NULL END SGMNT_NM '
END
SET @V_TMP_SQL_CUR=' FETCH NEXT FROM CUR_SCR_SUB_'+@V_BTCH_EXAM_ID+' into @V_SUB_ID'
EXEC (@V_TMP_SQL_CUR)
END----结束分段循环
---关闭课程游标
--CLOSE CUR_SCR_SUB;
--DEALLOCATE CUR_SCR_SUB;
SET @V_TMP_SQL_CUR= 'CLOSE CUR_SCR_SUB_'+@V_BTCH_EXAM_ID
EXEC (@V_TMP_SQL_CUR)
SET @V_TMP_SQL_CUR= 'DEALLOCATE CUR_SCR_SUB_'+@V_BTCH_EXAM_ID
EXEC (@V_TMP_SQL_CUR)
看那位高人指点一下怎么处理。
(另外一个非嵌套循环的已经成功执行)
作者: lyeer 发布时间: 2011-12-08
好长啊。。。

作者: fredrickhu 发布时间: 2011-12-08
聚焦一下,就是这一段:
SET @V_TMP_SQL_CUR = 'FETCH NEXT FROM CUR_SCR_SUB_'+@V_BTCH_EXAM_ID +' into @V_SUB_ID '
EXEC (@V_TMP_SQL_CUR)
共计科目数=4
@V_TMP_SQL_CUR=FETCH NEXT FROM CUR_SCR_SUB_20111208140702884 into @V_SUB_ID
消息 137,级别 15,状态 2,第 1 行
Must declare the scalar variable "@V_SUB_ID".
SET @V_TMP_SQL_CUR = 'FETCH NEXT FROM CUR_SCR_SUB_'+@V_BTCH_EXAM_ID +' into @V_SUB_ID '
EXEC (@V_TMP_SQL_CUR)
共计科目数=4
@V_TMP_SQL_CUR=FETCH NEXT FROM CUR_SCR_SUB_20111208140702884 into @V_SUB_ID
消息 137,级别 15,状态 2,第 1 行
Must declare the scalar variable "@V_SUB_ID".
作者: lyeer 发布时间: 2011-12-08
没申明这个变量
作者: rucypli 发布时间: 2011-12-08
变量在循环外层游标之前已经声明:
DECLARE @V_SUB_ID DECIMAL(18,0); --课程编码
{
---动态定义游标
---赋值给变量
---声明分段处理游标
---处理分段游标
--关闭分段处理游标
---关闭外层游标
}
大概是这个逻辑
DECLARE @V_SUB_ID DECIMAL(18,0); --课程编码
{
---动态定义游标
---赋值给变量
---声明分段处理游标
---处理分段游标
--关闭分段处理游标
---关闭外层游标
}
大概是这个逻辑
作者: lyeer 发布时间: 2011-12-08
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28