从 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 一起使用。