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

此代码有个问题,就是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、如果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

改成以下不完善

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:把第二个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 

结果: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 

结果: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 

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

你可能感兴趣的:(sqlserver,sqlserver,数据库,java)