SQL Server Try Catch 异常捕捉

SQL Server Try Catch 异常捕捉

背景

今天遇到一个关于try catch 使用比较有意思的问题。如下一段代码:

SELECT  @@TRANCOUNT AS A
BEGIN TRY
            BEGIN TRAN
            SELECT  @@TRANCOUNT AS A1

            INSERT  INTO A2A ( ID1 )
            VALUES  ( ‘A‘ )

            COMMIT TRAN;
END TRY
BEGIN CATCH
            SELECT  @@TRANCOUNT AS A2

            ROLLBACK TRAN; 

            SELECT  ERROR_MESSAGE() AS ErrorMessage ,
                    ERROR_SEVERITY() AS ErrorSeverity ,
                    ERROR_STATE() AS ErrorState
END CATCH  

SELECT  @@TRANCOUNT AS B

第一次执行时,无法正常捕捉到错误,并执行catch的代码,返回错误信息

第二次执行,就能正常捕捉。且后续再执行就都正常了。

同样的代码,执行2次出现完全不同的结果。这是很让人费解的。

分析

首先 看第一次执行报错,看这个错误的级别编号是16。
try catch 不能捕捉什么样的错误

严重级别为 10 或更低的错误,属于警告或信息性消息。
严重级别为 20 或更高且终止会话的 SQL Server 数据库引擎任务处理的错误。此类问题过于严重数据库引擎会直接终止会话。所以无法往后继续执行。

总之,就是能捕捉严重级别大于10,且不会严重到之前终止会话的错误

关于严重级别 和 描述:
https://docs.microsoft.com/zh-cn/sql/relational-databases/errors-events/database-engine-error-severities?view=sql-server-2017 “数据库引擎错误严重性”

那我们前面的例子错误级别16,的确是属于可以捕捉的情况。那为什么会有这个问题。跟执行计划的产生有关系。因为你第一次执行的时候,SQL server 在需要编译SQL 语句,产生执行计划。就是这个时候执行计划还没有。所以他无法往下面继续执行。就无法CATCH到。第二次,以及后面几次再执行,因为已经缓存了执行计划。所以可以catch到。

我们执行完第一次之后可以查看对应的执行计划

然后再执行,就可以成功捕捉了。如果我们把执行计划清除掉
DBCC FREEPROCCACHE 或者使用option(recomplile)进行重编译。那么结果就会是一直无法捕捉。

原文地址:https://www.cnblogs.com/Siny0/p/11190034.html

时间: 2024-08-05 12:42:52

SQL Server Try Catch 异常捕捉的相关文章

SQL Server Profiler -- 识别异常

SQL Server Profiler -- 识别异常 在一个完美的环境中,所有的异常都应该可以被捕捉.处理并记录.有专人定期查看这些日志并创建基于发生的异常的错误报告,使它们可以被及时调试并在将来多能避免再次发生.然而,现实总是可以看到应用程序从数据库到用户界面都会不断地出现各种异常,并且这些异常都没有任何记录.更糟糕的是,应用程序搜索到并消化了这些异常,偶尔也会给用户返回奇怪的数据,而这些用户并不明白发生了什么.为了查明这些情况通常提出分析观察这些异常,以便能够查找并处理这些异常,避免影响太

SQL Server 事务、异常和游标

建议先阅读存储过程:SQL Server 存储过程 ? 事务 在数据库中有时候需要把多个步骤的指令当作一个整体来运行,这个整体要么全部成功,要么全部失败,这就需要用到事务. 1. 事务的特点 事务有若干条T-SQL指令组成,并且所有的指令昨晚一个整体提交给数据库系统,执行时,这组指令要么全部执行完成,要么全部取消.因此,事务是一个不可分割的逻辑单元. 事务有4个属性:原子性(Atomicity).一致性(Consistency).隔离性(Isolation)以及持久性(Durability),也

SQL Server Try Catch错误处理

一.语法要点:BEGIN TRY     { sql_statement | statement_block } END TRY BEGIN CATCH           [ { sql_statement | statement_block } ] END CATCH [ ; ] 异常部分: 在 CATCH 块的作用域内,可以使用以下系统函数来获取导致 CATCH 块执行的错误消息: ERROR_NUMBER() 返回错误号. ERROR_SEVERITY() 返回严重性. ERROR_ST

SQL Server Profiler工具

一.SQL Profiler工具简介 SQL Profiler是一个图形界面和一组系统存储过程,其作用如下: 图形化监视SQL Server查询: 在后台收集查询信息: 分析性能: 诊断像死锁之类的问题: 调试T-SQL语句: 模拟重放SQL Server活动: 也可以使用SQL Profiler捕捉在SQL Server实例上执行的活动.这样的活动被称为Profiler跟踪. 1.Profiler跟踪 从开始=>所有程序=>Microsoft SQL Server 2008=>性能工具

SQL Server Profiler(转载)

SQL Server Profiler工具 一.SQL Profiler工具简介 SQL Profiler是一个图形界面和一组系统存储过程,其作用如下: 图形化监视SQL Server查询: 在后台收集查询信息: 分析性能: 诊断像死锁之类的问题: 调试T-SQL语句: 模拟重放SQL Server活动: 也可以使用SQL Profiler捕捉在SQL Server实例上执行的活动.这样的活动被称为Profiler跟踪. 1.Profiler跟踪 从开始=>所有程序=>Microsoft SQ

SQL Server Profiler工具【转】

一.SQL Profiler工具简介 转自:http://www.cnblogs.com/kissdodog/p/3398523.html SQL Profiler是一个图形界面和一组系统存储过程,其作用如下: 图形化监视SQL Server查询: 在后台收集查询信息: 分析性能: 诊断像死锁之类的问题: 调试T-SQL语句: 模拟重放SQL Server活动: 也可以使用SQL Profiler捕捉在SQL Server实例上执行的活动.这样的活动被称为Profiler跟踪. 1.Profil

SQL Server 开发指南

SQL Server 数据库设计 一.数据库设计的必要性     二.什么是数据库设计     三.数据库设计的重要     四.数据模型          实体-关系(E-R)数据模型         实体(Entity)         属性(Attribute)         关系(Relationship)     五.数据库设计步骤         1. 需求分析阶段         2. 概要设计阶段         3. 详细设计阶段     六.数据库设计规范化        

SQL Server 执行计划操作符详解(1)——断言(Assert

前言: 很多很多地方对于语句的优化,一般比较靠谱的回复即使--把执行计划发出来看看.当然那些只看语句就说如何如何改代码,我一直都是拒绝的,因为这种算是纯蒙.根据本人经验,大量的性能问题单纯从语句来看很难发现瓶颈,同一个语句,由于环境的不同,差距非常大,所以比较合适的还是分析执行计划. 那么对于执行计划,一般使用图形化执行计划就差不多了,但是用过的人也有一些疑惑,里面的图标(称为操作符)并不非常直观.所以从本文开始,会整理一些不怎么常见但由比较重要的操作符并进行解释,对于那些表扫描.索引扫描.聚集

[转]SQL Server 存储过程 一些常用用法(事物、异常捕捉、循环)

Transact-SQL中的存储过程,非常类似于Java语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句.这样就可以提高存储过程的性能. ? 存储过程的概念 存储过程Procedure是一组为了完成特定功能的SQL语句集合,经编译后存储在数据库中,用户通过指定存储过程的名称并给出参数来执行. 存储过程中可以包含逻辑控制语句和数据操纵语句,它可以接受参数.输出参数.返回单个或多个结果集以及返回值. 由于存储过程在创建时即在数据库服务器上进