• Sqlserver Try Catch时Catch捕获到错误则重试一次的写法


    最初代码如下:

    BEGIN TRY
    	EXECUTE sys.sp_testlinkedserver @LogicalName
            SET @SQLOnline = 1
    END TRY
    BEGIN CATCH
    	SET @SQLOnline = 0
    	print ERROR_MESSAGE()
    END CATCH
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    此代码有个问题,就是linked server一旦无法连接就报错了,没有重试功能,我们希望第一次出错后,可以有第二次重试机会,如果第二次重试也出错了,那么就算出错

    改成如下正确

    BEGIN
         BEGIN TRY
    	     EXECUTE sys.sp_testlinkedserver @LogicalName
    	     SET @SQLOnline = 1
        END TRY
        BEGIN CATCH
    	     SET @SQLOnline = 0
    	     print ERROR_MESSAGE()
        END CATCH
    
        IF @SQLOnline = 0 
        BEGIN
    	BEGIN TRY
    		EXECUTE sys.sp_testlinkedserver @LogicalName
    		SET @SQLOnline = 1
    	END TRY
    	BEGIN CATCH
    		SET @SQLOnline = 0
    		print ERROR_MESSAGE()
    	END CATCH  
        END			
    END
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    得出结论:
    1、如果IF后面没有ELSE,则IF后面的第一个BEGIN…END语句块受IF的条件影响,第二个BEGIN…END语句块不受IF的条件影响,特殊情况BEGIN TRY…END TRY和BEGIN CATCH…END CATCH是一体的,如果他们两者放入IF后面,不会因为两个BEGIN就会导致BEGIN CATCH…END CATCH不受IF管控
    2、这种Try Catch的,直接在Try使用while重试一次不太好,如果try catch在游标里面,这样的话每个游标记录都要在try里面执行两次。还是需要等到Catch的结果来重试比较合适,所有用IF比较合适

    改成以下错误

    BEGIN TRY			
            DECLARE @Counter int;  
            SET @Counter = 1;  
            WHILE @Counter <3  
            BEGIN  
    	EXECUTE sys.sp_testlinkedserver @LogicalName
            SELECT @Counter  
            SET @Counter = @Counter + 1 
    	PRINT  @Counter		
            END 
    	SET @SQLOnline = 1
    END TRY
    
    BEGIN CATCH
    	SET @SQLOnline = 0
    	print ERROR_MESSAGE()
    END CATCH
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    改成以下不完善

    BEGIN
         BEGIN TRY
    	     EXECUTE sys.sp_testlinkedserver @LogicalName
                 SET @SQLOnline = 1
         END TRY
         BEGIN CATCH
    	     SET @SQLOnline = 0
    	     print ERROR_MESSAGE()
         END CATCH
         PRINT @SQLOnline
    
         IF @SQLOnline = 0 
             BEGIN TRY
    	         EXECUTE sys.sp_testlinkedserver @LogicalName
                     SET @SQLOnline = 1
    	 END TRY
    	 BEGIN CATCH
    		SET @SQLOnline = 0
    		print ERROR_MESSAGE()
    	 END CATCH  
         PRINT @SQLOnline 
    END
    PRINT @SQLOnline
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    案例1:把第二个PRINT @SQLOnline 放END CATCH外面,并且不是IF后面第一个BEGIN里面,第二个PRINT @SQLOnline被打印出来了

    declare @SQLOnline int;
    set @SQLOnline=0
    IF @SQLOnline = 0 
    BEGIN
        BEGIN TRY
    		 select 1
             SET @SQLOnline = 1
    	END TRY
        BEGIN CATCH
    			SET @SQLOnline = 0
    			print ERROR_MESSAGE()
        END CATCH
    			PRINT @SQLOnline
    			WAITFOR DELAY '00:00:03';
       IF @SQLOnline = 0 
    			BEGIN TRY
    				select 1/0
    				SET @SQLOnline = 1
    			END TRY
    			BEGIN CATCH
    				SET @SQLOnline = 0
    				print ERROR_MESSAGE()
    			END CATCH  
    			PRINT @SQLOnline 
    END
    PRINT @SQLOnline 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    结果:message有如下信息
    (1 row(s) affected)
    1
    1
    1

    案例2:把第二个PRINT @SQLOnline 放END CATCH里面,第二个PRINT

    @SQLOnline没有打印出来了
    declare @SQLOnline int;
    set @SQLOnline=0
    IF @SQLOnline = 0 
    BEGIN
        BEGIN TRY
    		 select 1
             SET @SQLOnline = 1
    	END TRY
        BEGIN CATCH
    			SET @SQLOnline = 0
    			print ERROR_MESSAGE()
        END CATCH
    			PRINT @SQLOnline
    			WAITFOR DELAY '00:00:03';
       IF @SQLOnline = 0 
    			BEGIN TRY
    				select 1/0
    				SET @SQLOnline = 1
    			END TRY
    			BEGIN CATCH
    				SET @SQLOnline = 0
    				print ERROR_MESSAGE()
    				PRINT @SQLOnline 
    			END CATCH  			
    END
    PRINT @SQLOnline 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    结果:message有如下信息
    (1 row(s) affected)
    1
    1

    案例3:把第二个PRINT @SQLOnline 放END CATCH外面,但是放在IF后面第一个BEGIN里面,第二个PRINT @SQLOnline没有打印出来了

    declare @SQLOnline int;
    set @SQLOnline=0
    IF @SQLOnline = 0 
    BEGIN
         BEGIN TRY
    	     select 1
    	     SET @SQLOnline = 1
        END TRY
        BEGIN CATCH
    	     SET @SQLOnline = 0
    	     print ERROR_MESSAGE()
        END CATCH
    	PRINT @SQLOnline   
        WAITFOR DELAY '00:00:03';
    
        IF @SQLOnline = 0 
        BEGIN
    	BEGIN TRY
    		select 1
    		SET @SQLOnline = 1
    	END TRY
    	BEGIN CATCH
    		SET @SQLOnline = 0
    		print ERROR_MESSAGE()
    	END CATCH  
    	PRINT @SQLOnline 
        END			
    END
    PRINT @SQLOnline 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    结果:message有如下信息
    (1 row(s) affected)
    1
    1

  • 相关阅读:
    手把手Java爬虫教学 - 8. 项目2 - 数据库表设计 & 爬虫代码实现
    2-分类问题 SVM 核函数
    酌情参考——chatGPT给的一些语义框架的学术思路,语义和图谱结合似乎是个不错的方向
    Grafana+loki+promtail 收集logback微服务日志
    加满油箱问题
    java设计模式之组合设计模式
    删除表
    AXera-pi使用使用记录(1)
    机器人控制器编程实践指导书旧版-实践六 LCD液晶显示(点阵)
    Vue 移动端(H5)项目怎么实现页面缓存(即列表页面进入详情返回后列表页面缓存且还原页面滚动条位置)keep-alive缓存及清除keep-alive缓存
  • 原文地址:https://blog.csdn.net/lusklusklusk/article/details/127737734