最初代码如下:
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