SQL 2005 try catch

1TRY…CATCH

1.1用法

TRY…CATCH的语法如下:

BEGINTRY--TRY模块

--业务处理

ENDTRY

BEGINCATCH--CATCH模块

--错误处理

ENDCATCH

BEGIN TRYEND TRY中的是TRY模块;BEGIN CATCHEND CATCH之间是CATCH模块。TRY模块中的任何一条T-SQL出错时,将跳到CATCH模块(TRY模块中,出错的T-SQL后的语句不会被执行)。

1.2错误处理函数

使用TRY…CATCH时,必须在CATCH模块中对错误处理处理,如果不处理,则SQL Server不会给出任何提示,这样就不会知道是否有错误发生。

CATCH模块中,可以使用下面的这些函数来实现错误处理(这些函数只能用在CATCH模块中),在其他位置使用时,这些函数返回NULL值。

nERROR_NUMBER()返回错误号

nERROR_MESSAGE()返回错误消息的完整文本。此文本包括为任何可替换参数(如长度、对象名或时间)提供的值

nERROR_SEVERITY()返回错误严重性

nERROR_STATE()返回错误状态号

nERROR_LINE()返回导致错误的例程中的行号

nERROR_PROCEDURE()返回出现错误的存储过程或触发器的名称

1.3使用TRY…CATCH时的注意事项

使用TRY…CATCH时,需要注意下述事项:

nCATCH模块必须紧跟在TRY模块之后

nTRY…CATCH构造可以嵌套。这意味着可以将TRY…CATCH构造放置在其他TRY模拟和CATCH模块内。当嵌套的TRY块中出现错误时,程序控制将传递到与嵌套的TRY块关联的CATCH

n严重性为10或更低的错误被视为警告或信息性消息,这种错误不会导致处理跳到CATCH模块(通过RAISERROR抛出的自定义错误同样适用于此规则)。参考下面的T-SQL代码段进行测试。

BEGINTRY

--业务处理

RAISERROR('start',10,1)--此句不会导致处理转到CATCH模块

RAISERROR('warning',11,1)--此句会导致处理转到CATCH模块

RAISERROR('finish',10,1)--由于上一句导致处理转到CATCH模块,故此句不会被执行

ENDTRY

BEGINCATCH

--错误处理

SELECT

ERROR_MESSAGE()--返回warning

ENDCATCH

2TRY…CATCH andTransaction

2.1XACT_STATE()函数

一般在TRY…CATCH中使用事务时,会在TRY模块提交(COMMIT)事务;而在CATCH块回滚(ROLLBACK)事务。

如果要准确的控制事务的提交和回滚,则可以通过XACT_STATE()函数判断当前事务的状态,以进一步确定如何进行事务处理。

XACT_STATE()函数在SQL Server 2005及其之后的版本中可用,该函数返回下列值:

n0当前请求没有活动的用户事务

n1当前请求有活动的用户事务。请求可以执行任何操作,包括写入数据和提交事务

n-1当前请求具有活动的用户事务,但法提交事务或回滚到保存点;它只能请求完全回滚事务

2.2嵌套事务与事务保存点

SQL Server中的事务处理可以嵌套。可以通过全局变量@@TRANCOUNT查询当前连接的活动事务数(也就是事务嵌套的层数)。如果该变量值为0,则表示当前连接没有启用任何事务;如果该变量值>1,则表示当前连接存在事务嵌套。

SQL Server自动维护全局变量@@TRANCOUNT的值。当使用BEGIN TRANSACTION语句时,SQL Server@@TRANCOUNT1;使用COMMIT TRANSACTIONCOMMIT WORK时,SQL Server@@TRANCOUNT递减1;而使用ROLLBACK TRANSACTION时(不包括使用ROLLBACK TRANSACTION savepoint_name的情况),所有的事务都被回滚,对应的,@@TRANCOUNT直接递减为0

嵌套事务一般出现在嵌套存储过程时,但一般不建议使用嵌套事务,这会增加事务控制的难度。一般建议的事务处理方法,是在可能出现嵌套事务的地方,通过判断@@TRANCOUNT的值来确定当前的事务数,如果当前没有事务,则开启新的事务;如果已经有事务,则使用SAVE TRANSACTION savepoint_name语句设置事务保存点,以便在需要回滚当前处理的时候,可以通过ROLLBACK TRANSACTION savepoint_name语句将事务回滚到保存点。

3Template

下面是一个涉及TRY…CATCH和事务处理的模板。可以参考这个模板来编写业务存储过程,如果业务处理不涉及事务,则可以去掉事务处理的那些部分。

CREATEPROCprocedure_name

AS

SETNOCOUNTON

--当前的事务数

DECLARE

@__trancountint

SELECT

@__trancount=@@TRANCOUNT

-- TRY...CATCH处理

BEGINTRY

-- ========================================

--标准的事务处理模块块

-- a.开启事务,或者设置事务保存点

IF@__trancount=0

BEGINTRAN

ELSE

SAVETRAN__TRAN_SavePoint

-- b.这里放置处于事务中的各种处理语句

-- c.提交事务

--有可提交的事务,并且事务是在当前模块中开启的情况下,才提交事务

IFXACT_STATE()=1AND@__trancount=0

COMMIT

-- ========================================

-- ========================================

--为了防止TRY中有遗漏的事务处理,可以在TRY模拟的结束部分做最终的判断

IF@__trancount=0

BEGIN

IFXACT_STATE()=-1

ROLLBACKTRAN

ELSE

BEGIN

WHILE@@TRANCOUNT>0

COMMITTRAN

END

END

ENDTRY

BEGINCATCH

-- ========================================

--CATCH模块,应该首先处理事务

IFXACT_STATE()<>0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值