• Sql Server 中关于@@ERROR的一个小小误区


       我们经常写存储过程的时候会用到@@ERROR来判断执行是否成功,很久没有写复杂点的存储过程了,今天发现前段时间写的一个proc出现了bug,由于定义参数时,字符串长度设的有点短,导致传进来的值中间被截断,出现数据错乱的问题,才发现最后的一句:

    IF(@@ERROR<>0)
         BEGIN
         ROLLBACK TRAN
         END 

    前面明明已经出错了,可是在这里@@ERROR 一直都是0,这时才发现问题,下面举例说明,

    	DECLARE @NowTime DATETIME; 
    
    		BEGIN TRAN
    
    		RAISERROR ('假设这里抛出异常!',16,1);
    
            SET @NowTime=GETDATE();
    
            IF ( @@ERROR <> 0 )
                 BEGIN
    
                    SELECT ERROR_MESSAGE() Result;
    
                    ROLLBACK TRAN
    
    			 END 
            ELSE
                    SELECT  'Success' Result;
                    COMMIT TRAN


    例如上面的语句中,我在执行获取当前时间之前,抛出了一个异常,那么按照我们想要的它应该回滚当前事务,输出ERROR_MESSAGE()错误信息,可实际上执行的结果是“Success”,看到这里不由的想到另一个与之类似的默认的参数,@@IDENTITY,这个可以返回sql执行最后依次的标识值,我们知道如果@@IDENTITY不紧跟你最后的sql语句的时候,那么你无法获取想要的结果,这里的@@ERROR也是类似的,所以原因就很明显了,我抛出异常后,下面接着执行的是 SET @NowTime=GETDATE(); 这条语句是没有错误的,所以最终@@ERROR始终是0,所以最后事务还是提交了,另外注意下@@ERROR并不是获取的错误的次数,而是有一定含义的错误码。

    那么这种情况该如何解决呢,很简单,TRY  CATCH ,真的是很久不写存储过程了,忽略了这一点,当其中一条语句出现异常时,立马抛出异常并接收异常,回滚事务就可以了,作出如下修改:

    		DECLARE @NowTime DATETIME; 
    
    		BEGIN TRY
    
    		BEGIN TRAN
    
    		RAISERROR ('假设这里抛出异常!',16,1);
    
            SET @NowTime=GETDATE();
    
    		COMMIT TRAN;
    		
    		SELECT  'Success' Result;
    
    		END TRY
    
    		BEGIN CATCH
    
    		SELECT @@ERROR Error;
    		
    		SELECT ERROR_MESSAGE()  Result;
    		
    		ROLLBACK TRAN
    
    		END CATCH

    执行结果如下:


    所以记住,以后再写复杂的存储过程或者用到事务的时候最好加上TRY CATCH 。

  • 相关阅读:
    WPF and Silverlight 学习笔记:键盘输入、鼠标输入、焦点处理
    [转]Visual Studio .NET "目标平台" 说明
    WPF 使用HwndHost嵌入Win32后,无法接受Mouse_Move\Mouse_Leave消息
    c#有多少种可能导致写文件失败?
    优化性能:文本【msdn】
    解决popup不随着window一起移动的问题
    异常处理的资料
    利用bat编译WPF项目
    属性值继承
    WPF消息机制
  • 原文地址:https://www.cnblogs.com/Allen0910/p/7354100.html
Copyright © 2020-2023  润新知