-1

假设我有以下 SQL Server 存储过程:

CREATE PROC TestSP AS
select 'results selected' as column1
RAISERROR('this is an error',16,1)
--RETURN 3

如果我这样称呼它,

DECLARE @ReturnCode int
EXEC @ReturnCode = TestSP
select @ReturnCode as ReturnCode

返回码将为-6。如果我ALTER PROC取消注释--RETURN 3存储过程中的行并再次调用它,RETURN 3 将覆盖并导致返回码为 3。

如果我从 TRY...CATCH 块中调用该过程,

DECLARE @ReturnCode int
BEGIN TRY
    EXEC @ReturnCode = TestSP
END TRY
BEGIN CATCH
    PRINT 'An error occurred.'
END CATCH
SELECT @ReturnCode as ReturnCode

返回码将为 NULL。

使用的返回码 ( EXEC @ReturnCode = TestSP) 是否与从 TRY...CATCH 块中调用存储过程不兼容?

4

1 回答 1

0

从 TRY...CATCH 块调用返回码时返回码为 NULL 的原因可能与批量中止有关。

正如您所说,Microsoft SQL Server 为程序员提供了以捕获返回代码的方式执行存储过程的选项:

EXEC @ReturnCode = YourStoredProc

但您也可以选择从 TRY...CATCH 块中调用您的存储过程,就像这样

BEGIN TRY
    EXEC YourStoredProc
END TRY
BEGIN CATCH
    <handle error>
END CATCH

EXEC @ReturnCode = YourStoredProc如果您要从 TRY...CATCH 块调用存储过程,似乎没有必要调用它,因为正如您所指出的,返回码将为 NULL。(旁注:如果您的代码中没有 TRY...CATCH 或显式 'RETURN n ',RAISERROR 会将返回码设置为 -1 表示错误严重性为 11,-2 表示 12,-3 表示 13 等. 但是请注意,小于 20 的严重性不会停止代码的执行。)

TRY..CATCH 方法为您提供了更多选项和信息来处理错误。在 CATCH 块内,您可以使用以下系统函数(取自TRY...CATCH 文档):

  • ERROR_NUMBER() 返回错误的编号。
  • ERROR_SEVERITY() 返回严重性。
  • ERROR_STATE() 返回错误状态编号。
  • ERROR_PROCEDURE() 返回发生错误的存储过程或触发器的名称。
  • ERROR_LINE() 返回导致错误的例程中的行号。
  • ERROR_MESSAGE() 返回错误消息的完整文本。文本包括为任何可替代参数提供的值,例如长度、对象名称或时间。

您可以使用以下代码测试这些函数的输出:

BEGIN TRY
    EXEC TestSP  --A stored proc fashioned to cause an error
END TRY
BEGIN CATCH
    SELECT
    'ERROR_NUMBER()', ERROR_NUMBER(),''
    UNION SELECT
    'ERROR_SEVERITY()',ERROR_SEVERITY(),''
    UNION SELECT
    'ERROR_STATE() ',ERROR_STATE(),''
    UNION SELECT
    'ERROR_PROCEDURE()',0,ERROR_PROCEDURE()
    UNION SELECT
    'ERROR_LINE()',ERROR_LINE(),''
    UNION SELECT
    'ERROR_MESSAGE()',0,ERROR_MESSAGE()
END CATCH

最后,应该注意的是,当在从 TRY...CATCH 块调用的存储过程中使用 RAISERROR 时,严重性 <= 10 甚至不被视为错误,并且不会导致调用代码中的 CATCH 块触发。严重性 11+ 将导致 CATCH 块触发。在大多数情况下,我们应该将严重级别 16 与 RAISERROR 一起使用。

于 2015-10-28T22:59:50.803 回答