使用TRY CATCH应该注意的一个小细节
来源:互联网 发布:淘宝网2017女装秋装 编辑:程序博客网 时间:2024/05/22 13:09
最近看到一个文章,关于try-catch失效的问题做了说明,我觉得解释了很多之前遇到的很奇怪的问题,放在博客的记录下这个事
群里一个朋友遇到一个TRY CATCH的小问题,测试后发现是自己从来没有考虑的情况,写篇blog加深下印象
--=========================================================
在MSDN上对TRY CATCH有如下描述:
对 Transact-SQL 实现与 Microsoft Visual C# 和 Microsoft Visual C++ 语言中的异常处理类似的错误处理。Transact-SQL 语句组可以包含在 TRY 块中。如果 TRY 块内部发生错误,则会将控制传递给 CATCH 块中包含的另一个语句组。
--=========================================================
在TRY CATCH未出现之前,我们使用@@ERROR,ERROR_STATE()等来判断语句是否正常运行,再根据情况来处理事务,随着TRY CATCH的出现,我们可以将事务语句写成如下方式:
--开启事务BEGIN TRAN BEGIN TRY --执行一些逻辑操作 INSERT INTO TB1(ID)VALUES(1) --提交事务 COMMIT TRANEND TRYBEGIN CATCH --回滚事务 ROLLBACK TRANEND CATCH
可当我们执行以下语句(不创建临时表#TB)
BEGIN TRAN BEGIN TRY INSERT INTO #TB SELECT 1 PRINT 'COMMIT TRAN'; COMMIT TRAN;END TRYBEGIN CATCH SELECT ERROR_MESSAGE() AS ErrorMessage ,ERROR_SEVERITY() AS ErrorSeverity ,ERROR_STATE() AS ErrorState PRINT 'ROLLBACK TRAN'; ROLLBACK TRAN;END CATCH
由于#TB没有创建,因此在执行中发生异常,错误提示如下:
消息 102,级别 15,状态 1,第 24 行“对”附近有语法错误。
这个错误很容易理解,因为#TB不存在,但这不是重点,重点是CATCH部分的语句没有被执行,事务没有被提交也没有被回滚(如果程序中有类似问题,那就严重咯)。
继续阅读MSDN,可以找到如下解释:
不受 TRY…CATCH 构造影响的错误TRY…CATCH 构造在下列情况下不捕获错误:严重级别为 10 或更低的警告或信息性消息。严重级别为 20 或更高且终止会话的 SQL Server 数据库引擎任务处理的错误。如果所发生错误的严重级别为 20 或更高,而数据库连接未中断,则 TRY…CATCH 将处理该错误。需要关注的消息,如客户端中断请求或客户端连接中断。当系统管理员使用 KILL 语句终止会话时。如果以下类型的错误的发生级别与 TRY…CATCH 构造的执行等级相同,则 CATCH 块不会处理这些错误:编写错误,例如禁止运行批处理的语法错误。语句级重新编写过程中出现的错误,例如由于名称解析延迟而造成在编写后出现对象名解析错误。这些错误会被返回到运行批处理、存储过程或触发器的级别。
经过对比分析,我们遇到的问题应该属于“语句级重新编写过程中出现的错误,例如由于名称解析延迟而造成在编写后出现对象名解析错误。”的情况。
--==============================================================
如果有类似的问题,我们应该如何处理呢?
解决办法1: 在对#TB处理前先判断其是否存在
解决办法2:将对#TB的操作语句放入的EXEC(@SQL)
BEGIN TRAN BEGIN TRY EXEC('INSERT INTO #TB SELECT 1') PRINT 'COMMIT TRAN'; COMMIT TRAN;END TRYBEGIN CATCH SELECT ERROR_MESSAGE() AS ErrorMessage ,ERROR_SEVERITY() AS ErrorSeverity ,ERROR_STATE() AS ErrorState PRINT 'ROLLBACK TRAN'; ROLLBACK TRAN;END CATCH
执行以上代码,会发现同样是严重级别16的错误,这次可以被传递到CATCH块中处理。
--=======================================================
很多人说细节决定成败,学习SQL SERVER的路上,有很多类似的小知识点,平时很难遇到,遇到时也很容易颠覆下我们自认为的“真理”,这个时候,多看看MSDN还是很管用的!
- 使用TRY CATCH应该注意的一个小细节
- 使用Spring AOP应该注意的一个小细节
- 开发时应该注意的小细节
- 点击事件应该注意的小细节
- 重写equals应该注意的一个细节
- 使用mysql应该注意的细节
- try catch 的使用
- try...catch的使用
- try catch语句中遇见的一个小问题
- c++ #ifndef注意的一个小细节
- 日志,IOCP中一些应该注意的小细节
- 开发中应该注意的小细节二
- try catch finally 细节
- 使用OpenCV需要注意的小细节
- svn使用注意的小细节
- 使用OpenCV需要注意的小细节
- oracle应该注意的细节
- JS try.....catch的使用
- Hibernate 缓存机制GOOD
- rockmongo 操作
- 全自动软化水设备:全自动软化水设备保养方法概述
- javascript的取整函数
- keil C编译error : expected a ")"
- 使用TRY CATCH应该注意的一个小细节
- pymongo group的用法
- HDU 2680 Choose the best route
- JAVA中String,StringBuffer与StringBuilder的区别
- 读取Flex AIR应用程序设置
- 西门子PLC学习笔记三(S7-300信号模块)
- 逆向教程->游戏中的U3D付费模式分析
- AngularJS入门(六)
- Android下的消息推送的原理分析