@@ ERROR和/或TRY - CATCH

KM.*_*KM. 15 t-sql sql-server sql-server-2005

Try-Catch会捕获@@ ERROR可以发现的所有错误吗?在下面的代码片段中,检查@@ ERROR是否值得?RETURN 1111会发生吗?

SET XACT_ABORT ON
BEGIN TRANSACTION

BEGIN TRY
    --do sql command here  <<<<<<<<<<<

    SELECT @Error=@@ERROR
    IF @Error!=0
    BEGIN
        IF XACT_STATE()!=0
        BEGIN
            ROLLBACK TRANSACTION
        END
        RETURN 1111
    END

END TRY
BEGIN CATCH

    IF XACT_STATE()!=0
    BEGIN
        ROLLBACK TRANSACTION
    END
    RETURN 2222

END CATCH

IF XACT_STATE()=1
BEGIN
    COMMIT
END

RETURN 0
Run Code Online (Sandbox Code Playgroud)

A-K*_*A-K 14

以下文章是Erland Sommarskog,SQL Server MVP必读的:使用存储过程实现错误处理

另请注意,您的TRY块可能会失败,并且您的CATCH块可能会被绕过

还有一件事:当与TRY ... CATCH块一起使用时,使用旧式错误处理和保存点的存储过程可能无法正常工作.避免混合新旧错误处理方式.

  • Erland Sommarskog的链接文章适用于SQL Server 2000.有关SQL Server 2005的文章,请访问:http://www.sommarskog.se/error_handling_2005.html (4认同)

gbn*_*gbn 8

TRY/CATCH陷阱更多.它非常棒,而且非常好.

DECLARE @foo int

SET @foo = 'bob' --batch aborting pre-SQL 2005
SELECT @@ERROR
GO
SELECT @@ERROR  --detects 245. But not much use, really if the batch was a stored proc
GO


DECLARE @foo int
BEGIN TRY
    SET @foo = 'bob'
    SELECT @@ERROR
END TRY
BEGIN CATCH
    SELECT ERROR_MESSAGE(), ERROR_NUMBER()
END CATCH
GO
Run Code Online (Sandbox Code Playgroud)

在触发器中使用TRY/CATCH也有效.触发器回滚过去也是批量中止:如果触发器中也使用了TRY/CATCH,则不再使用.

如果BEGIN/ROLLBACK/COMMIT位于构造内部而不是外部,那么您的示例会更好