以文本方式查看主题 - Foxtable(狐表) (http://foxtable.net/bbs/index.asp) -- 专家坐堂 (http://foxtable.net/bbs/list.asp?boardid=2) ---- 游标循环出错时如何跳到下一个值继续执行? (http://foxtable.net/bbs/dispbbs.asp?boardid=2&id=125473) |
-- 作者:happyft -- 发布时间:2018/9/28 20:37:00 -- 游标循环出错时如何跳到下一个值继续执行? 在sql的数据表字段修改后有的视图可能会出错,所以用游标遍历所有视图检查, ... DECLARE @name VARCHAR(40); OPEN MyCursor; FETCH NEXT FROM MyCursor INTO @name; WHILE ( @@fetch_status <> -1 )
BEGIN IF ( @@fetch_status <> -2 ) BEGIN BEGIN TRY EX EC sp_
END TRY BEGIN CATCH SET @names = @names +
\',\' + @name --记录出错的视图 如何转到下面的绿色语句进入下一个值循环 END CATCH; END;
FETCH NE XT FROM MyCursor
INTO @name;
END; CLOSE MyCursor;
DEALLOCATE MyCursor;
PRINT @names; 目的就是想实现 ,当检查一个视图出错时,将此视图名@name记下,再循环检查下一个视图,直到全部检查完成打印出所有出错的视图. 上面的代码执行出错时就停止了,应该如何才能实现? 谢谢! |
-- 作者:有点蓝 -- 发布时间:2018/9/28 21:04:00 -- 下面代码单独放到一个存储过程中,调用 BEGIN
BEGIN TRY
EX EC sp_refreshview @name;
END TRY
BEGIN CATCH
SET @names = @names + \',\' + @name --记录出错的视图
如何转到下面的绿色语句进入下一个值循环
END CATCH; END; |
-- 作者:HappyFt -- 发布时间:2018/9/29 10:40:00 -- 主储存过程如下: ALTER PROCEDURE [dbo].[usp_RefreshAllView] @name2 VARCHAR(40) OUTPUT AS DECLARE @names NVARCHAR(MAX); DECLARE @name VARCHAR(40); DECLARE MyCursor CURSOR FOR SE LECT name FROM dbo.sysobjects WHERE OBJECTPROPERTY(id, N\'IsView\') = 1 AND ( NOT name IN ( \'sysconstraints\', \'syssegments\' ) ); OPEN MyCursor; FETCH NEXT FROM MyCursor INTO @name; WHILE ( @@fetch_status <> -1 ) BEGIN IF ( @@fetch_status <> -2 ) BEGIN EX EC usp_RefreshAllViewchk @name, @name2 OUTPUT --接收出错返回的值 SE T @names = @names + \',\' + @name2; --集合出错的视图 END; FETCH NE XT FROM MyCursor INTO @name; END; CLOSE MyCursor; DEALLOCATE MyCursor; PRINT @names; 调用的子储存过程如下 ALTER PROCEDURE [dbo].[usp_RefreshAllViewchk] ( @name VARCHAR(40) , @name2 VARCHAR(40) OUTPUT ) AS BEGIN BEGIN TRY EX EC sp_refreshview @name; END TRY BEGIN CATCH SE T @name2 = @name; RETURN @name2; END CATCH; END; 运行主储存过程,当出现第一个有错的视图时出错, 消息 245,级别 16,状态 1,过程 usp_RefreshAllViewchk,第 14 行 在将 varchar 值 \'uv_sc002\' 转换成数据类型 int 时失败。 哪里 的问题? 谢谢! |
-- 作者:有点蓝 -- 发布时间:2018/9/29 10:58:00 -- RETURN @name2;去掉 |
-- 作者:HappyFt -- 发布时间:2018/9/29 11:12:00 -- 去掉执行变成这样了: 消息 266,级别 16,状态 2,过程 usp_RefreshAllViewchk,第 0 行 EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 0,当前计数 = 1。
|
-- 作者:有点蓝 -- 发布时间:2018/9/29 11:28:00 -- RETURN @name2; 改为 RETURN 0; 或者试试 ALTER PROCEDURE [dbo].[usp_RefreshAllViewchk] ( @name VARCHAR(40) , @name2 VARCHAR(40) OUTPUT ) AS BEGIN set nocount on BEGIN TRY EX EC sp_refreshview @name; END TRY BEGIN CATCH SE T @name2 = @name; END CATCH; set nocount off END; |
-- 作者:HappyFt -- 发布时间:2018/9/29 11:37:00 -- 还是不行,两种方式 结果都一样 消息 266,级别 16,状态 2,过程 usp_RefreshAllViewchk,第 0 行 EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 0,当前计数 = 1。 消息 266,级别 16,状态 2,过程 usp_RefreshAllView,第 0 行 EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 0,当前计数 = 1。 (1 行受影响) (1 行受影响) 消息 3998,级别 16,状态 1,第 1 行 在批处理结束时检测到不可提交的事务。该事务将回滚。 |
-- 作者:有点蓝 -- 发布时间:2018/9/29 12:30:00 -- 测试了一下TRYCATCH不会影响游标的处理,出错后会继续处理下一个,不能打印出出错视图的原因是没有初始化@names ALTER PROCEDURE [dbo].[usp_RefreshAllView] @name2 VARCHAR(MAX) OUTPUT AS begin DECLARE @names NVARCHAR(MAX); DECLARE @name VARCHAR(40);
SET @names = \'\'; DECLARE MyCursor CURSOR FOR SELECT name FROM dbo.sysobjects WHERE OBJECTPROPERTY(id, N\'IsView\') = 1 AND ( NOT name IN ( \'sysconstraints\', \'syssegments\' ) ); OPEN MyCursor; FETCH NEXT FROM MyCursor INTO @name; WHILE ( @@fetch_status <> -1 ) BEGIN IF ( @@fetch_status <> -2 ) BEGIN BEGIN TRY EXEC sp_refreshview @name; END TRY BEGIN CATCH SET @names = @names + \',\' + @name --记录出错的视图 END CATCH; END; FETCH NEXT FROM MyCursor INTO @name; END; CLOSE MyCursor; DEALLOCATE MyCursor; PRINT @names; end [此贴子已经被作者于2018/9/29 12:31:41编辑过]
|
-- 作者:HappyFt -- 发布时间:2018/9/29 14:30:00 -- 还是有问题: 当出现第一个出错的视图后,后面的每一个游标值(视图)都按出错的来处理了,实际后面打印出来的很多视图都是正确的,也就是出错一次就没有再执行begin tray而是统统都按begin catch来执行了.
|
-- 作者:有点蓝 -- 发布时间:2018/9/29 15:13:00 -- 我测试正常,有问题的才会记录。至于上面的错误应该不是这里引起的 BEGIN TRY
EXEC sp_refreshview @name;
SET @names = @names + \',ok=\' + @name --记录正确的视图 END TRY BEGIN CATCH
SET @names = @names + \',*********\' + @name --记录出错的视图 END CATCH; 我的测试结果是 ,ok=vGetSubList,ok=vChoiceQuestionDetail,ok=vJudgmentQuestionDetail,ok=vCodingQuestionDetail,ok=vAnswerList,*********vUsersTestGroup,*********vGetUsersQuestionCount,ok=vAllSubjectCount,ok=vQuestionAmount,ok=vGetQuestionTypeLevelCount,ok=vCheckUpdateTime,*********vGetUserLastAnswerDate,ok=vIgnoreQuestions,ok=vConsecutiveError5Times,*********vGetAnswerQuestionCount,*********vGetUserErrorQuestions |