3

由于 X_TEST 列不存在,我预计会出现错误。但是错误没有被异常块捕获。

BEGIN TRY
   SELECT X_TEST FROM ACCOUNTS 
END TRY
BEGIN CATCH
   PRINT 'There was an error! ' + ERROR_MESSAGE()
END CATCH

为什么 ?是因为错误的严重性吗?

4

3 回答 3

3

不,TRY 只能处理其自身范围内的某些类型的错误。现在,你说你有一个看起来像这样的存储过程(在non_existent_column被删除之后):

CREATE PROCEDURE dbo.blat
AS
BEGIN
  BEGIN TRY
    SELECT non_existent_column FROM dbo.table_that_exists;
  END TRY
  BEGIN CATCH
    PRINT ERROR_MESSAGE();
  END CATCH
END
GO

如果你只是这样做......

EXEC dbo.blat;

...您将因编译错误而受到重创,因为该 TRY 范围内的语句无法解析:

Msg 207, Level 16, State 1, Procedure fooblat, Line 5
Invalid column name 'non_existent_column'.

但是,您可以在外部范围内捕获此错误(无论过程是否TRY/CATCH存在):

BEGIN TRY
  EXEC dbo.fooblat;
END TRY
BEGIN CATCH
  PRINT 'There was an error:';
  PRINT ERROR_MESSAGE();
END CATCH

结果(注意这不是例外,文本不再是红色):

There was an error:
Invalid column name 'non_existent_column'.

您也可以使用动态 SQL 来避免这种情况,但似乎您已经将其击落,所以这是我能想到的下一个最佳建议 - 在外部范围内捕获错误。

于 2012-04-19T01:25:15.643 回答
2

使用不存在的列是语法错误。您的批处理甚至从未开始执行。

考虑这段代码:

BEGIN TRY
   sdgedtju§$%&/()= 
END TRY
BEGIN CATCH
   PRINT 'There was an error! ' + ERROR_MESSAGE()
END CATCH

你不会期望它甚至开始,对吧?它不编译。使用不存在的列是一样的

于 2012-04-19T00:28:12.490 回答
2

这段代码会给你你期望看到的行为......

BEGIN TRY
   exec('SELECT X_TEST FROM ACCOUNTS')
END TRY
BEGIN CATCH
   PRINT 'There was an error! ' + ERROR_MESSAGE()
END CATCH
于 2012-04-19T00:36:18.760 回答