zoukankan      html  css  js  c++  java
  • @@ERROR, BEGIN TRY/CATCH and XACT_ABORT

    oday I am showing you the difference between @@ERROR, BEGIN TRY/CATCH and XACT_ABORT
    The three alternatives to error handling works little different and let us intercept the error handling in different stages in the process.

    First I am going to show you the ordinary @@ERROR check which most of you are used to.
     
    IF OBJECT_ID('uspTest_2000') IS NOT NULL
               DROP PROCEDURE uspTest_2000
    GO
    CREATE PROCEDURE uspTest_2000
    AS
     
    CREATE TABLE          #Sample
                          (
                                     i TINYINT
                          )
     
    BEGIN TRANSACTION
     
    INSERT     #Sample
    SELECT     209
     
    IF @@ERROR <> 0
               BEGIN
                          ROLLBACK TRANSACTION
                          PRINT 'Insert Error (User defined error message)'
               END
    ELSE
               BEGIN
                          COMMIT TRANSACTION
                          PRINT 'Insert OK (User defined error message)'
               END
     
    DROP TABLE #Sample
    GO
    DECLARE    @rc INT
     
    SELECT     @rc AS rc,
               @@TRANCOUNT AS [TransactionCount]
     
    EXEC       @rc = uspTest_2000
     
    SELECT     @rc AS rc,
               @@TRANCOUNT AS [TransactionCount]
     
    As you can see, the code works ok and no error is generated. You also get two resultsets back with in-going and out-going value for @rc variable.
     
    In SQL Server 2005 BEGIN TRY/CATCH was introduced and can be written like this.
     
    IF OBJECT_ID('uspTest_2005') IS NOT NULL
               DROP PROCEDURE uspTest_2005
    GO
    CREATE PROCEDURE uspTest_2005
    AS
     
    CREATE TABLE          #Sample
                          (
                                     i TINYINT
                          )
     
    BEGIN TRY
               BEGIN TRANSACTION
     
               INSERT     #Sample
               SELECT     209
     
               COMMIT TRANSACTION
               PRINT 'Insert OK (User defined error message)'
    END TRY
     
    BEGIN CATCH
               ROLLBACK TRANSACTION
               PRINT 'Insert Error (User defined error message)'
               PRINT ERROR_MESSAGE()
    END CATCH
     
    DROP TABLE #Sample
    GO
     
    DECLARE    @rc INT
     
    SELECT     @rc AS rc,
               @@TRANCOUNT AS [TransactionCount]
     
    EXEC       @rc = uspTest_2005
     
    SELECT     @rc AS rc,
               @@TRANCOUNT AS [TransactionCount]
     
    As you can see, we again get two resultsets back with in-going and out-going values for @rc.
     
    In SQL Server 2005 and SQL Server 2008 we also have the option of  XACT_ABORT.
    You can see here how that is written.
     
    IF OBJECT_ID('uspTest_2008') IS NOT NULL
               DROP PROCEDURE uspTest_2008
    GO
    CREATE PROCEDURE uspTest_2008
    AS
     
    SET XACT_ABORT ON
     
    CREATE TABLE          #Sample
                          (
                                     i TINYINT
                          )
     
    INSERT     #Sample
    SELECT     209
     
    DROP TABLE #Sample
    GO
    DECLARE    @rc INT
     
    SELECT     @rc AS rc,
               @@TRANCOUNT AS [TransactionCount]
     
    EXEC       @rc = uspTest_2008
     
    SELECT     @rc AS rc,
               @@TRANCOUNT AS [TransactionCount]
     
    And again we get two resultset back with in-going and out-going values for @rc.
    So far so good.
    The interesting part begins when error occurs. We can easily produce an error by inserting the value of 2090 instead of 209 in the SMALLINT column. 
     
    IF OBJECT_ID('uspTest_2000') IS NOT NULL
               DROP PROCEDURE uspTest_2000
    GO
    CREATE PROCEDURE uspTest_2000
    AS
     
    CREATE TABLE          #Sample
                          (
                                     i TINYINT
                          )
     
    BEGIN TRANSACTION
     
    INSERT     #Sample
    SELECT     2090
     
    IF @@ERROR <> 0
               BEGIN
                          ROLLBACK TRANSACTION
                          PRINT 'Insert Error (User defined error message)'
               END
    ELSE
               BEGIN
                          COMMIT TRANSACTION
                          PRINT 'Insert OK (User defined error message)'
               END
     
    DROP TABLE #Sample
    GO
    DECLARE    @rc INT
     
    SELECT     @rc AS rc,
               @@TRANCOUNT AS [TransactionCount]
     
    EXEC       @rc = uspTest_2000
     
    SELECT     @rc AS rc,
               @@TRANCOUNT AS [TransactionCount]
     
    Yes, we do get two resultsets back, and we also get two error messages!
    SQL Server delivers a collection of error messages back to the client! This  collection has two error messages; first one for SQL Server internal and the other is the user defined error message.
     
    Msg 220, Level 16, State 2, Procedure uspTest_2000, Line 11
    Arithmetic overflow error for data type tinyint, value = 2090.
    The statement has been terminated.
    Insert Error (User defined error message)
     
    What happens then with BEGIN TRY/CATCH?
     
    IF OBJECT_ID('uspTest_2005') IS NOT NULL
               DROP PROCEDURE uspTest_2005
    GO
    CREATE PROCEDURE uspTest_2005
    AS
     
    CREATE TABLE          #Sample
                          (
                                     i TINYINT
                          )
     
    BEGIN TRY
               BEGIN TRANSACTION
     
               INSERT     #Sample
               SELECT     2090
     
               COMMIT TRANSACTION
               PRINT 'Insert OK (User defined error message)'
    END TRY
     
    BEGIN CATCH
               ROLLBACK TRANSACTION
               PRINT 'Insert Error (User defined error message)'
               PRINT ERROR_MESSAGE()
    END CATCH
     
    DROP TABLE #Sample
    GO
     
    DECLARE    @rc INT
     
    SELECT     @rc AS rc,
               @@TRANCOUNT AS [TransactionCount]
     
    EXEC       @rc = uspTest_2005
     
    SELECT     @rc AS rc,
               @@TRANCOUNT AS [TransactionCount]
     
    The big difference is that now the internal error message provided by SQL Server is not displayed automatically!

    Luckily we also have more error function to use besides the one you see in the code above;  ERROR_MESSAGE.
    One of those is named ERROR_LINE which gives you the line number for the statement generating the error!
    With BEGIN TRY/CATCH we have the option to decide which error message to display and in which order.
     
    Insert Error (User defined error message)
    Arithmetic overflow error for data type tinyint, value = 2090.
     
    How does then XACT_ABORT work? 
     
    IF OBJECT_ID('uspTest_2008') IS NOT NULL
               DROP PROCEDURE uspTest_2008
    GO
    CREATE PROCEDURE uspTest_2008
    AS
     
    SET XACT_ABORT ON
     
    CREATE TABLE          #Sample
                          (
                                     i TINYINT
                          )
     
    INSERT     #Sample
    SELECT     2090
     
    DROP TABLE #Sample
    GO
    DECLARE    @rc INT
     
    SELECT     @rc AS rc,
               @@TRANCOUNT AS [TransactionCount]
     
    EXEC       @rc = uspTest_2008
     
    SELECT     @rc AS rc,
               @@TRANCOUNT AS [TransactionCount]
     
    The big difference is that we don't have to explicit handle our transactions. SQL Server automatically does a rollback.
    The other difference is that all code after the error is skipped.
     
    You can tell due to now there is only one resultset which contains the in-going value for @rc.


    Refer:

    http://weblogs.sqlteam.com/peterl/archive/2009/04/07/ERROR-BEGIN-TRYCATCH-and-XACT_ABORT.aspx

  • 相关阅读:
    jquery validate自定义checkbox验证规则和样式
    【转】maven导出项目依赖的jar包
    maven web项目build失败
    【转】maven仓库快速镜像
    【转】javax.net.ssl.SSLHandshakeException(Cas导入证书)
    Maven发布web项目到tomcat
    tomcat启动是报Multiple Contexts have a path of "/XXX"
    spring无法扫描jar包的问题
    CAS单点登录之mysql数据库用户验证及常见问题
    搭建CAS单点登录服务器
  • 原文地址:https://www.cnblogs.com/guanjie20/p/2467891.html
Copyright © 2011-2022 走看看