• sqlserver 存储过程 try catch TRANSACTION (转)


    原文:http://www.cnblogs.com/yun_shuai/archive/2010/09/20/1831546.html

    /*

    1. 轻微错误(严重性级别为0-10):默认情况下不会给客户程序发送错误消息,继续工作。也就是说它无法被CATCH到

    2. 中等错误(严重性级别为11-19):能够被CATCH到(不管是在T-SQL里面还是在客户程序里面)

    3. 严重错误(严重性级别为20-25):SQL Server将强制把连接关掉。很显然这也不可能被CATCH到


    【重点提示!!】

    由于业务的复杂或者系统性能问题,致使数据库sql语句执行较久。

    导致客户端网页已经连接超时(如设置为30秒)

    此时数据库批处理语句未执行完成,客户session断开,相当于中断操作,类似【案例1】的中断。

    事务是没有提交或回滚的,资源仍在占用,导致发生堵塞或死锁!~



    【解决方法】:

    在批处理语句前加上 SET XACT_ABORT ON
    当客户端中断的时候,未执行完成则回滚操作,及时释放资源。


    --查看 XACT_ABORT 是否打开
    SELECT (CASE WHEN (16384 & @@OPTIONS) = 16384 THEN 'ON' ELSE 'OFF' END) AS XACT_ABORT;


    */

    CREATE PROCEDURE YourProcedure    
    AS
    BEGIN
        SET NOCOUNT ON;

        BEGIN TRY---------------------开始捕捉异常
           BEIN TRAN------------------开始事务
            UPDATE A SET A.names = B.names FROM 表1 AS A INNER JOIN 表2 AS B ON A.id = B.id

            UPDATE A SET A.names = B.names FROM 表1 AS A INNER JOIN 表2 AS B ON A.TEST = B.TEST

        COMMIT TRAN -------提交事务
        END TRY-----------结束捕捉异常
        BEGIN CATCH------------有异常被捕获
            IF @@TRANCOUNT > 0---------------判断有没有事务
            BEGIN
                ROLLBACK TRAN----------回滚事务
            END 
            EXEC YourLogErrorProcedure-----------执行存储过程将错误信息记录在表当中
        END CATCH--------结束异常处理
    END

    ---------------------------------------------记录操作错信息的存储过程--------------------------------------------

    CREATE PROCEDURE YourLogErrorProcedure
        @ErrorLogID [int] = 0 OUTPUT -- contains the ErrorLogID of the row inserted
    AS                               -- by uspLogError in the ErrorLog table
    BEGIN
        SET NOCOUNT ON;

        -- Output parameter value of 0 indicates that error 
        -- information was not logged
        SET @ErrorLogID = 0;

        BEGIN TRY
            -- Return if there is no error information to log
            IF ERROR_NUMBER() IS NULL
                RETURN;

            -- Return if inside an uncommittable transaction.
            -- Data insertion/modification is not allowed when 
            -- a transaction is in an uncommittable state.
            IF XACT_STATE() = -1
            BEGIN
                PRINT 'Cannot log error since the current transaction is in an uncommittable state. ' 
                    + 'Rollback the transaction before executing uspLogError in order to successfully log error information.';
                RETURN;
            END

            INSERT [dbo].[OperateErrorLog] 
                (
                [OperateName], 
                [ErrorNumber], 
                [ErrorSeverity], 
                [ErrorState], 
                [ErrorProcedure], 
                [ErrorLine], 
                [ErrorMessage]
                ) 
            VALUES 
                (
                CONVERT(sysname, CURRENT_USER), 
                ERROR_NUMBER(),
                ERROR_SEVERITY(),
                ERROR_STATE(),
                ERROR_PROCEDURE(),
                ERROR_LINE(),
                ERROR_MESSAGE()
                );
            SET @ErrorLogID = @@IDENTITY;
        END TRY
        BEGIN CATCH
            PRINT 'An error occurred in stored procedure uspLogError: ';
            EXECUTE YourPrintErrorProcedure;-----------------打印错误信息的存储过程
            RETURN -1;
        END CATCH
    END;

    CREATE PROCEDURE YourPrintErrorProcedure
    AS
    BEGIN
        SET NOCOUNT ON;

        -- Print error information. 
        PRINT 'Error ' + CONVERT(varchar(50), ERROR_NUMBER()) +
              ', Severity ' + CONVERT(varchar(5), ERROR_SEVERITY()) +
              ', State ' + CONVERT(varchar(5), ERROR_STATE()) + 
              ', Procedure ' + ISNULL(ERROR_PROCEDURE(), '-') + 
              ', Line ' + CONVERT(varchar(5), ERROR_LINE());
        PRINT ERROR_MESSAGE();
    END;

    CREATE TABLE [dbo].[ErrorLog](
        [ErrorLogID] [int] IDENTITY(1,1) NOT NULL,
        [ErrorTime] [datetime] NOT NULL CONSTRAINT [DF_ErrorLog_ErrorTime]  DEFAULT (getdate()),
        [UserName] [sysname] COLLATE Chinese_PRC_CI_AS NOT NULL,
        [ErrorNumber] [int] NOT NULL,
        [ErrorSeverity] [int] NULL,
        [ErrorState] [int] NULL,
        [ErrorProcedure] [nvarchar](126) COLLATE Chinese_PRC_CI_AS NULL,
        [ErrorLine] [int] NULL,
        [ErrorMessage] [nvarchar](4000) COLLATE Chinese_PRC_CI_AS NOT NULL,
     CONSTRAINT [PK_ErrorLog_ErrorLogID] PRIMARY KEY CLUSTERED 
    (
        [ErrorLogID] ASC
    )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
    ) ON [PRIMARY]

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/WeiZhang_son_Ding/archive/2010/02/05/5291732.aspx

    http://www.cnblogs.com/BpLoveGcy/archive/2010/03/22/1691407.html

    ALTER PROC usp_AccountTransaction  

    1.     @AccountNum INT,  
    2.     @Amount DECIMAL  
    3. AS  
    4. BEGIN  
    5. BEGIN TRY --Start the Try Block..  
    6. BEGIN TRANSACTION -- Start the transaction..  
    7. UPDATE MyChecking SET Amount = Amount - @Amount  
    8. WHERE AccountNum = @AccountNum  
    9. UPDATE MySavings SET Amount = Amount + @Amount  
    10. WHERE AccountNum = @AccountNum  
    11. COMMIT TRAN -- Transaction Success!  
    12. END TRY  
    13. BEGIN CATCH  
    14.         IF @@TRANCOUNT > 0  
    15. ROLLBACK TRAN --RollBack in case of Error  
    16. -- you can Raise ERROR with RAISEERROR() Statement including the details of the exception  
    17.         --RAISERROR(ERROR_MESSAGE(), ERROR_SEVERITY(), 1)       

                DECLARE @ErrorMessage NVARCHAR(4000);
           DECLARE @ErrorSeverity INT;
         DECLARE @ErrorState INT;

         SELECT 
          @ErrorMessage = ERROR_MESSAGE(),
          @ErrorSeverity = ERROR_SEVERITY(),
          @ErrorState = ERROR_STATE();

       -- Use RAISERROR inside the CATCH block to return error
       -- information about the original error that caused
       -- execution to jump to the CATCH block.
         RAISERROR (@ErrorMessage, -- Message text.
              @ErrorSeverity, -- Severity.
              @ErrorState -- State.
              );

    1.   
    2.     END CATCH  
    3.   
    4. END  
    5.   
    6. GO  
    1. BEGIN TRY  
    2.   
    3.     SELECT GETDATE()  
    4.   
    5.     SELECT 1/0--Evergreen divide by zero example!  
    6.   
    7. END TRY  
    8.   
    9. BEGIN CATCH  
    10.   
    11.     SELECT 'There was an error! ' + ERROR_MESSAGE()  
    12.   
    13.     RETURN  
    14.   
    15. END CATCH;  

    2.获得错误信息的函数表: 

    下面系统函数在CATCH块有效.可以用来得到更多的错误信息:

    函数描述
    ERROR_NUMBER() 返回导致运行 CATCH 块的错误消息的错误号。
    ERROR_SEVERITY() 返回导致 CATCH 块运行的错误消息的严重级别
    ERROR_STATE() 返回导致 CATCH 块运行的错误消息的状态号
    ERROR_PROCEDURE() 返回出现错误的存储过程名称
    ERROR_LINE() 返回发生错误的行号
    ERROR_MESSAGE() 返回导致 CATCH 块运行的错误消息的完整文本
      •   BEGIN TRY  
      •   
      •     Try Statement 1  
      •   
      •     Try Statement 2  
      •   
      •     ...  
      •   
      •     Try Statement M  
      •   
      • END TRY  
      •   
      • BEGIN CATCH  
      •   
      •     Catch Statement 1  
      •   
      •     Catch Statement 2  
      •   
      •     ...  
      •   
      •     Catch Statement N  
      •   
      • END CATCH  
  • 相关阅读:
    如何快速定位到DBGrid的某一行!!!急...
    说说设计模式~单件模式(Singleton)
    EF架构~终于自己架构了一个相对完整的EF方案
    .Net——实现IConfigurationSectionHandler接口定义处理程序处理自定义节点
    在LINQ中实现多条件联合主键LEFT JOIN
    从LINQ开始之LINQ to Objects(上)
    WPF控件模板和数据模板
    WPF的ListView控件自定义布局用法实例
    初步探讨WPF的ListView控件(涉及模板、查找子控件)
    LINQ技巧:如何通过多次调用GroupBy实现分组嵌套
  • 原文地址:https://www.cnblogs.com/huaan011/p/4725123.html
Copyright © 2020-2023  润新知