zoukankan      html  css  js  c++  java
  • 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  
  • 相关阅读:
    推荐系统 蒋凡译 第一章 引言 读书笔记
    神经网络与深度学习 邱锡鹏 第5章 卷积神经网络 读书笔记
    神经网络与深度学习 邱锡鹏 第4章 前馈神经网络 读书笔记
    神经网络与深度学习 邱锡鹏 第3章 线性模型 读书笔记
    神经网络与深度学习 邱锡鹏 第2章 机器学习概述 读书笔记
    神经网络与深度学习 邱锡鹏 第1章 绪论 作业
    神经网络与深度学习 邱锡鹏 第1章 绪论 读书笔记
    算法笔记 上机训练实战指南 第13章 专题扩展 学习笔记
    算法笔记 第13章 专题扩展 学习笔记
    算法笔记 上机训练实战指南 第11章 提高篇(5)--动态规划专题 学习笔记
  • 原文地址:https://www.cnblogs.com/huaan011/p/4725123.html
Copyright © 2011-2022 走看看