标签归档:@@error

mssql sqlserver中@@error使用注意事项


摘要:
下文讲述sqlserver中@@error使用时的注意事项,如下所示:
实验环境:sql server 2008 R2

在sql脚本的编写中,经常看见同事这样采用以下的格式编写脚本:

if(@@error<>0)
    ROLLBACK TRANSACTION tranSaveName
else
    COMMIT TRANSACTION  tranSaveName
	

上文中@@error是一个上一条sql语句是否正确的标志,不是整个脚本的执行情况。
每一条sql脚本执行完毕后,会立即对@@error进行赋值

 
SET NOCOUNT ON;
 
BEGIN TRANSACTION tranNew

 /*sql脚本*/

RAISERROR ('抛出错误信息!',16,1)

SELECT GETDATE()

if(@@error<>0)
    ROLLBACK TRANSACTION tranNew
else
    COMMIT TRANSACTION tranNew
	


我们可以看出以上的sql脚本采用显示弹出错误,但是还是无法回滚事务,多方查询我们可以看出
if (@@error <>0) 这里的值永远都是true,因为@@error这里获取的执行状态为select getdate()函数的执行状态

那么对以上这种脚本的编写,我们应该采用try catch来进行异常捕捉

 SET NOCOUNT ON;
  
BEGIN TRY
    BEGIN TRANSACTION tranNew

   /*sql脚本*/

    RAISERROR ('抛出错误信息!',16,1)

    SELECT GETDATE()
    
    COMMIT TRANSACTION tranNew
END TRY
BEGIN CATCH
    DECLARE @msg nvarchar(2000)=ERROR_MESSAGE()                
    RAISERROR (@msg,16,1)     --抛出异常信息
    ROLLBACK TRANSACTION tranNew   --回滚
END CATCH

mssql sqlserver 深入理解@@error 变量-避免@@error误区


摘要:
下文讲述sqlserver中@@error变量的详细说明,如下所示:
实验环境:sql server 2008 R2



@@error 变量简介

@@error 是一个系统变量
@@error 返回当前执行语句的执行状态,当@@error 等于0时,代表sql语句执行成功,不等于0则代表sql执行失败
@@error 是一个动态计数器,它是一个系统变量,不能进行相关加减操作

@@error 常见写法

    if  (@@error <>0)
      begin 
          rollback tran; 
      end
    else
      begin
         commit tran; 
     end


@@error 误区

SET NOCOUNT ON;
 BEGIN tran 

UPDATE [maomao365.com]
SET info='测试信息'
WHERE  keyId =100

RAISERROR ('抛出错误!',16,1)

SELECT newId()

if(@@error<>0)
 begin
    ROLLBACK tran 
end
else
begin
    COMMIT  tran
end 
set nocount on 


以上的sql脚本 RAISERROR (‘抛出错误!’,16,1) 抛出sql错误,理论上@@error变量应该不等于0,但是当@@error判断时,数据还是被提交,那么为什么会出现这样的情况呢?
主要原因是:
RAISERROR抛出错误脚本运行后,@@error变为5000,但是当运行
select newid()后,因为sql脚本执行成功,@@error变量为0
最后if 判断时,@@error已经为0了,所以数据还是会被提交。
—处理方法:
方法1:使用try catch 语法对sql脚本进行包裹
方法2:在脚本运行后,及时对sql脚本进行判断

  ---方法1:
SET NOCOUNT ON;
BEGIN TRY
 BEGIN TRANSACTION 

UPDATE [maomao365.com]
SET info='测试信息'
WHERE  keyId =100

RAISERROR ('抛出错误!',16,1)

 SELECT newId()

COMMIT TRANSACTION
END TRY

BEGIN CATCH
    DECLARE @msg nvarchar(1000)=ERROR_MESSAGE()    --将错误信息放入@msg变量中              
    RAISERROR (@msg,16,1)   
    ROLLBACK TRANSACTION T ----回滚脚本
END CATCH
set nocount on 
go

 ---方法2:

SET NOCOUNT ON;
 BEGIN tran 
UPDATE [maomao365.com]
SET info='测试信息'
WHERE  keyId =100

RAISERROR ('抛出错误!',16,1)
if(@@error<>0)
 begin
    ROLLBACK tran  
   return;
end

SELECT newId()
if(@@error<>0)
 begin
    ROLLBACK tran 
end
else
begin
    COMMIT  tran
end 
set nocount on 

mssql sqlserver 正确使用@@error


摘要:
下文讲述在sql脚本编写时,我们应注意@@error的相关写法避免出现bug


在sql脚本编写中,我们常常使用@@error判断存储过程是否执行成功
例:

     DECLARE @a int; 
     BEGIN TRAN
      RAISERROR ('抛出异常-模拟错误',16,1);
     SET @a=99;
       IF  @@ERROR  <> 0 
             BEGIN
                 SELECT ERROR_MESSAGE() [错误信息];
                 ROLLBACK TRAN
             END 
        ELSE
             BEGIN
                SELECT  '执行成功'
                COMMIT TRAN
            END

以上语句,当我们模拟错误时,并通过一个@@error 判断错误数,并输出错误信息和回滚事务 ,但脚本返回的却是”执行成功”,此时我们通过仔细的分析脚本,发现在抛出错误后,增加了一句set @a =99 这条赋值命令一切运行正常,导致@@error的结果为0,所以事务得到正确的提交,即在使用@@error进行相关错误判断时,一定要在sql执行后立即进行相关判断。
————————————————————————————-
在sqlserver 2005以后的版本中,微软开放了try catch 的捕捉异常的方法,我们可以在脚本中采用 try catch的方式捕捉异常,可避免@@error写错位置导致的异常,如下:

DECLARE @a int; 
    BEGIN TRY 
     BEGIN TRAN
      RAISERROR ('抛出异常-模拟错误',16,1);
     SET @a=99;
     SELECT  '执行成功'
                COMMIT TRAN
    END TRY
    BEGIN CATCH 
                 SELECT ERROR_MESSAGE() [错误信息];
                 ROLLBACK TRAN
    END  CATCH

采用以上的方法编写脚本时,当try 中的脚本,运行异常时,会立即进入catch中进行相关运行。

注意事项:
@@error 只可判断前一条sql脚本是否执行正确。