在SQL Server中,我常常会看到有些前辈这样写:

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

一开始,我看见别人这么写,我就想当然的以为它只是个计数器,每当检测到一处错误时,@@error的值+1,不过就因为这个理所当然,所以杯具了...

实际上,它并不是一个计数器,它是一个动态的值,动态的标识最后一条SQL命令执行的结果,如果成功则为0,不成功则标识错误码。所以,像上面这种写法是不妥的,举个例子,如下:

SET NOCOUNT ON;
SET XACT_ABORT ON; --执行 Transact-SQL 语句产生运行时错误,则整个事务将终止并回滚 BEGIN TRANSACTION T UPDATE Test
SET a='已更新'
WHERE a='未更新' RAISERROR ('不好意思,你没有权限!',16,1) SELECT GETDATE() if(@@error<>0)
ROLLBACK TRANSACTION T
else
COMMIT TRANSACTION T

分析:

  按我以前的理解来说,【 RAISERROR ('不好意思,你没有权限!',16,1) 】这里抛出了一个错误,整个事务应该回滚才对,可是,它却没有回滚!!那么原因出在哪呢?原来,问题出在"SELECT GETDATE()"这句上面!因为执行RAISERROR语句时,@@error的值不为0(好像是5000),而当执行到下一句"SELECT GETDATE()"时,@@error的值又变为0了!所以,后面的if语句自然没有捕捉到任何错误...

对策:

  既然找到了原因,那解决办法自然也少不了。用Try...CATCH语法就可以了,语句如下:

SET NOCOUNT ON;
SET XACT_ABORT ON; --执行 Transact-SQL 语句产生运行时错误,则整个事务将终止并回滚 BEGIN TRY
BEGIN TRANSACTION T UPDATE Test
SET a='已更新'
WHERE a='未更新' RAISERROR ('不好意思,你没有权限!',16,1) SELECT GETDATE() COMMIT TRANSACTION T
END TRY
BEGIN CATCH
DECLARE @msg nvarchar(2000)=ERROR_MESSAGE() --将捕捉到的错误信息存在变量@msg中
RAISERROR (@msg,16,1) --此处才能抛出(好像是这样子....)
ROLLBACK TRANSACTION T  --出錯回滾事務
END CATCH

SQL Server 中关于 @@error 的一个小误区的更多相关文章

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

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

  2. Sql Server 中的 @@ERROR

    @@ERROR:当前一个语句遇到错误,则返回错误号,否则返回0.需要注意的是@ERROR在每一条语句执行后会被立刻重置,因此应该在要验证的语句执行后检查数值或者是将它保存到局部变量中以备将来使用. D ...

  3. SQL Server中事务、锁定和阻塞

    事务是什么 在SQL Server中事务是构成一个工作逻辑单元的一系列任务,也就说多个任务放在一起执行,这些任务要么全部执行成功,要么全部执行失败. 通过事务我们可以保证数据的完整性,例如:用户A给用 ...

  4. SQL点滴9—SQL Server中的事务处理以及SSIS中的内建事务

    原文:SQL点滴9-SQL Server中的事务处理以及SSIS中的内建事务 我们可以把SSIS中的整个package包含在一个事务中,但是如果在package的执行过程中有一个表需要锁定应该怎么处理 ...

  5. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

  6. 在 SQL Server 中使用 Try Catch 处理异常

    如何在 SQL Server 中使用 Try Catch 处理错误? 从 SQL Server 2005 开始,我们在TRY 和 CATCH块的帮助下提供了结构错误处理机制.使用TRY-CATCH的语 ...

  7. SQL Server中SELECT会真的阻塞SELECT吗?

    在SQL Server中,我们知道一个SELECT语句执行过程中只会申请一些意向共享锁(IS) 与共享锁(S), 例如我使用SQL Profile跟踪会话86执行SELECT * FROM dbo.T ...

  8. SQL SERVER 中如何获取日期(一个月的最后一日、一年的第一日等等)

    https://blog.csdn.net/deepwishly/article/details/9101307 这是计算一个月第一天的SQL 脚本:   SELECT DATEADD(mm, DAT ...

  9. Sql Server 中一个非常强大的日期格式化函数

    Sql Server 中一个非常强大的日期格式化函数Select CONVERT(varchar(100), GETDATE(), 0)-- 05 16 2006 10:57AMSelect CONV ...

随机推荐

  1. ios 学习常用网站

    一 ,别的blog上的内容 iPhone 4 与iPad开发基础教程 一.邮件列表: 1.cocoa-dev http://lists.apple.com/mailman/listinfo/cocoa ...

  2. java继承3个小题

    1.实现一个名为Person的类和它的子类Employee,Employee有两个子类Faculty和Staff.具体要求如下: (1)Person类中的属性有:姓名name(String类型),地址 ...

  3. Git 操作 学习资源 网址

    用git 有一段时间了,有点自己的小心得.个人觉得相对SVN来讲他更灵活,更合理. 陆陆续续的收集了一些学习资源: 1.理解Xcode 中的Git 版本控制 http://www.open-open. ...

  4. Leetcode 110 Balanced Binary Tree 二叉树

    判断一棵树是否是平衡树,即左右子树的深度相差不超过1. 我们可以回顾下depth函数其实是Leetcode 104 Maximum Depth of Binary Tree 二叉树 /** * Def ...

  5. 重学JAVA基础(六):多线程的同步

    1.synchronized关键字 /** * 同步关键字 * @author tomsnail * @date 2015年4月18日 下午12:12:39 */ public class SyncT ...

  6. Hadoop学习篇 2 初识 Hadoop

    在一个全配置的集群上,运行Hadoop意味着在网络分布的不同服务器上运行一组守护进程 (daemons),这些守护进程或运行在单个服务器上,或运行与多个服务器上,他们包括: (1) NameNode( ...

  7. BarManager.ContextMenu

    <!--Search & List Area--> <dxb:BarManager Name="barManager1" dxlc:DockLayoutC ...

  8. DataGridView隔行显示不同的颜色

      如果该dataGridView是跟数据库绑定的,则可以触发DataBindingComplete事件:  1private   void   dataGridView1_DataBindingCo ...

  9. ASP.NET MVC验证标注的扩展-checkbox必选

    我们知道ASP.NET mvc提供一些表单的验证标注,比如必填属性RequiredAttribute 但是这个属性不适合选择框的必选 但是很多时候,我们却是需要一些必选的单选框 比如网站注册的时候,需 ...

  10. eclipse android logcat 只显示自己应用程序信息的设置方法

    1 elcipse 中往往会在logcat中显示 all message ,而这里面的信息太多,根本没有办法进行区分.如图: 2 我们想显示自己项目的 logcat .下面开始设置. 3 首先点击上面 ...