设为首页 收藏本站
查看: 646|回复: 0

[经验分享] SQL 2005 try catch

[复制链接]

尚未签到

发表于 2016-11-10 09:15:53 | 显示全部楼层 |阅读模式
1TRY…CATCH
1.1用法
TRY…CATCH的语法如下:
BEGINTRY--TRY模块
--业务处理
ENDTRY
BEGINCATCH--CATCH模块
--错误处理
ENDCATCH
在BEGIN TRY和END TRY中的是TRY模块;BEGIN CATCH和END 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将@@TRANCOUNT加1;使用COMMIT TRANSACTION或COMMIT 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

line-height: 15.75pt; margin: 0cm 0cm 0pt; background: #d9

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-298261-1-1.html 上篇帖子: SQL中时间的加减 下篇帖子: Pro*C动态SQL总结3
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表