Foxtable(狐表)用户栏目专家坐堂 → 游标循环出错时如何跳到下一个值继续执行?


  共有3501人关注过本帖树形打印复制链接

主题:游标循环出错时如何跳到下一个值继续执行?

帅哥哟,离线,有人找我吗?
happyft
  1楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:八尾狐 帖子:1930 积分:17564 威望:0 精华:0 注册:2014/7/29 19:09:00
游标循环出错时如何跳到下一个值继续执行?  发帖心情 Post By: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_refreshview @name;

                    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;



此主题相关图片如下:tim截图20180928202552.jpg
按此在新窗口浏览图片

目的就是想实现 ,当检查一个视图出错时,将此视图名@name记下,再循环检查下一个视图,直到全部检查完成打印出所有出错的视图.
上面的代码执行出错时就停止了,应该如何才能实现?
谢谢!


 回到顶部
帅哥,在线噢!
有点蓝
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:超级版主 帖子:110630 积分:563058 威望:0 精华:9 注册:2015/6/24 9:21:00
  发帖心情 Post By: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
  3楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:八尾狐 帖子:1930 积分:17564 威望:0 精华:0 注册:2014/7/29 19:09:00
  发帖心情 Post By: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 时失败。
哪里 的问题?
谢谢!


 回到顶部
帅哥,在线噢!
有点蓝
  4楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:超级版主 帖子:110630 积分:563058 威望:0 精华:9 注册:2015/6/24 9:21:00
  发帖心情 Post By:2018/9/29 10:58:00 [只看该作者]

RETURN @name2;去掉

 回到顶部
帅哥哟,离线,有人找我吗?
HappyFt
  5楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:八尾狐 帖子:1930 积分:17564 威望:0 精华:0 注册:2014/7/29 19:09:00
  发帖心情 Post By:2018/9/29 11:12:00 [只看该作者]

去掉执行变成这样了:
消息 266,级别 16,状态 2,过程 usp_RefreshAllViewchk,第 0 行
EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 0,当前计数 = 1。

 回到顶部
帅哥,在线噢!
有点蓝
  6楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:超级版主 帖子:110630 积分:563058 威望:0 精华:9 注册:2015/6/24 9:21:00
  发帖心情 Post By: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
  7楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:八尾狐 帖子:1930 积分:17564 威望:0 精华:0 注册:2014/7/29 19:09:00
  发帖心情 Post By: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 行
在批处理结束时检测到不可提交的事务。该事务将回滚。


 回到顶部
帅哥,在线噢!
有点蓝
  8楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:超级版主 帖子:110630 积分:563058 威望:0 精华:9 注册:2015/6/24 9:21:00
  发帖心情 Post By: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
  9楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:八尾狐 帖子:1930 积分:17564 威望:0 精华:0 注册:2014/7/29 19:09:00
  发帖心情 Post By:2018/9/29 14:30:00 [只看该作者]

还是有问题:


图片点击可在新窗口打开查看此主题相关图片如下:tim截图20180928202552.jpg
图片点击可在新窗口打开查看

当出现第一个出错的视图后,后面的每一个游标值(视图)都按出错的来处理了,实际后面打印出来的很多视图都是正确的,也就是出错一次就没有再执行begin tray而是统统都按begin catch来执行了.

 回到顶部
帅哥,在线噢!
有点蓝
  10楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:超级版主 帖子:110630 积分:563058 威望:0 精华:9 注册:2015/6/24 9:21:00
  发帖心情 Post By: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


 回到顶部
总数 24 1 2 3 下一页