关于SQLSERVER 事物的运用
概述:以往在SQL2000下处理异常通常的方式比较繁琐,SQL2005版本以上加入了Begin Try End/try Begin Cath End Catch 是异常的捕获稍微显得简单一些,根据我的测试,将我对SQL事物的处理做一下整理;本文分为三个部分来描述,重点讲述对SQL2005以上版本对事物的处理,SQL2000略过了。第一部分:针对普通的事物描述。第二部分针对自定义错误的抛出以及回滚。第三部分:嵌套事物以及嵌套的存储过程的回滚;
第一部分:针对普通的事物描述
1》 基本语法描述
BEGIN TRAN
SELECT 1/0
INSERT INTO TABLE1 SELECT 1
COMMIT TRAN
如果这样是这样执行,SELECT 1/0是明显的错误,但数据1还是被插入到Table1中,
不能达到要么全部执行成功,要么就全部回滚的机制,为什么?因为没有进行异常的捕获,如何进行异常的捕获,通常有以下三种方式
1》利用@@ERROR每执行一条语句进行判断@ERROR的状态,其代码如下
BEGIN TRAN
SELECT 1/0
IF@@ERROR>0GOTOERR
INSERTINTO TABLE1 SELECT 1
COMMIT TRAN
RETURN
ERR:
ROLLBACK TRAN
小结:利用@@ERROR对执行的结果进行判断,如果错误,跳转到ERR标签,并回滚
2》利用SETXACT_ABORTon语句如下
SET XACT_ABORT on
BEGIN TRAN
SELECT 1/0
INSERT INTO T_Test SELECT 12
COMMIT TRAN
小结:当开启了SETXACT_ABORTon 之后只要在程序内部发生错误都会自动执行回滚
3》利用Begin Try End Try /Begin Catch EndCatch
BEGIN TRY
BEGIN TRAN
SELECT 1/0
INSERTINTOT_Test SELECT 12
COMMIT TRAN
END TRY
BEGIN CATCH
DECLARE @ERR VARCHAR(30)=ERROR_MESSAGE()
ROLLBACK TRAN
RAISERROR( @ERR,17, 1)
END CATCH
小结:(17,1),是定义的错误等级,我随便搞的,可以通过系统特性取得这些值, BEGIN CATCH /END CATCH主要是对执行语句执行的异常部分进行捕获,并人为的抛出异常,捕获的内容有
ERROR_MESSAGE()错误的信息;
ERROR_NUMBER(),错误的行数;
ERROR_SEVERITY(),错误的等级;
ERROR_STATE(),错误的状态;
ERROR_PROCEDURE(),错误的存储过程(含嵌套的存储过程)
第一部分的小结:
通过以上的三种方式都可以实现异常的捕获,而进行事物的回滚,三种方式各有什么优劣呢,@@ROWCOUNT不用想,很烦人,我认为没有什么优势
SET ABORT ON 很好,一句话就可以解决,出现的异常,无论是执行的异常,还是自定义的异常(下一部分描述),都可以处理,但对于嵌套的异常输出没有好的解决方案
BEIGN TRY END TRY方式语法上稍微繁琐点,但对于异常的输出,特别是嵌套的存储过程的异常输出的处理上更加的详尽些(第三部分讲述)