TRY...CATCH使用范例

BEGIN TRY
//逻辑语句块
END TRY
BEGIN CATCH
//Catch异常处理块
SET @msg = ERROR_MESSAGE();
PRINT @msg;
END CATCH;

使用 TRY...CATCH 构造时,请遵循下列规则和建议:

  • 每个 TRY...CATCH 构造都必须位于一个批处理、存储过程或触发器中。例如,不能将 TRY 块放置在一个批处理中而将关联的 CATCH 块放置在另一个批处理中。

  • CATCH 块必须紧跟 TRY 块。

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

  • 若要处理给定的 CATCH 块中出现的错误,请在指定的 CATCH 块中编写 TRY...CATCH 块。

  • TRY...CATCH 块不处理导致数据库引擎关闭连接的严重性为 20 或更高的错误。但是,只要连接不关闭,TRY...CATCH 就会处理严重性为 20 或更高的错误。

  • 严重性为 10 或更低的错误被视为警告或信息性消息,TRY...CATCH 块不处理此类错误。

  • 即使批处理位于 TRY...CATCH 构造的作用域内,关注消息仍将终止该批处理。分布式事务失败时,Microsoft 分布式事务处理协调器 (MS DTC) 将发送关注消息。MS DTC 用于管理分布式事务。

错误函数详解

TRY...CATCH 使用下列错误函数来捕获错误信息:

  • ERROR_NUMBER() 返回错误号。

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

  • ERROR_SEVERITY() 返回错误严重性。

  • ERROR_STATE() 返回错误状态号。

  • ERROR_LINE() 返回导致错误的例程中的行号。

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

可以使用这些函数从 TRY...CATCH 构造的 CATCH 块的作用域中的任何位置检索错误信息。如果在 CATCH 块的作用域之外调用错误函数,错误函数将返回 NULL。在 CATCH 块中执行存储过程时,可以在存储过程中引用错误函数并将其用于检索错误信息。如果这样做,则不必在每个 CATCH 块中重复错误处理代码。在下面的代码示例中,TRY 块中的 SELECT 语句将生成一个被零除错误。此错误将由 CATCH 块处理,它将使用存储过程返回错误信息。

BEGIN TRY
-- Generate divide-by-zero error.
SELECT 1/0;
END TRY
BEGIN CATCH
-- Execute the error retrieval routine.
EXECUTE usp_GetErrorInfo;
END CATCH;
GO

编译错误和语句级重新编译错误

对于与 TRY...CATCH 构造在同一执行级别发生的错误,TRY...CATCH 将不处理以下两类错误:

  • 编译错误,例如阻止批处理执行的语法错误。

  • 语句级重新编译过程中出现的错误,例如由于名称解析延迟而造成在编译后出现对象名解析错误。

当包含 TRY...CATCH 构造的批处理、存储过程或触发器生成其中一种错误时,TRY...CATCH 构造将不处理这些错误。这些错误将返回到调用生成错误的例程的应用程序或批处理。例如,下面的代码示例显示导致语法错误的 SELECT 语句。如果在 SQL Server Management Studio 查询编辑器中执行此代码,则由于批处理无法编译,执行将不启动。错误将返回到查询编辑器,将不会由 TRY...CATCH 捕获。

USE Wot_Inventory;
GO BEGIN TRY
-- This PRINT statement will not run because the batch
-- does not begin execution.
PRINT N'Starting execution'; -- This SELECT statement contains a syntax error that
-- stops the batch from compiling successfully.
SELECT ** FROM Wot_Inventory.dbo.Invoice
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
GO

与上述示例中的语法错误不同,语句级重新编译过程中发生的错误不会阻碍批处理进行编译,但是一旦语句重新编译失败,它会立即终止批处理。例如,如果批处理含有两条语句并且第二条语句引用的表不存在,则延迟的名称解析会使该批处理成功进行编译并开始执行(无需将缺少的表绑定到查询计划),直到重新编译该语句为止。批处理到达引用缺失表的语句时将停止运行,并返回一个错误。在发生错误的执行级别,TRY...CATCH 构造将不处理此类错误。

有关详细信息,请参阅处理数据库引擎错误中的“在 Transact-SQL 中使用 TRY...CATCH”一节。

PS:欢迎扫描下方二维码或点击链接,加入QQ群

Sql语法高级应用之六:如何在Sql语句中如何使用TRY...CATCH的更多相关文章

  1. Sql语法高级应用之七:如何在存储过程中使用事务

    普通事物: USE Wot_Inventory; GO BEGIN TRANSACTION tr; DECLARE @error INT; SET @error = 0; SELECT * FROM ...

  2. Sql语法高级应用之一:使用sql语句如何实现不同的角色看到不同的数据

    前言 在常见的管理系统中,通常都有这样的需求,管理员可以看到所有数据,部门可以看到本部门的数据,组长可以看到自己组的数据,组员只能看到自己相关的数据. 一般人的做法是,根据不同的角色通过if...el ...

  3. Entity Framework 异常: 'OFFSET' 附近有语法错误。\r\n在 FETCH 语句中选项 NEXT 的用法无效。

    在使用 EF 的时候,突然发现更新后在服务器中运行出错,异常信息主要包含以下信息: 'OFFSET' 附近有语法错误.\r\n在 FETCH 语句中选项 NEXT 的用法无效.\r\n关键字 'AS' ...

  4. Entity Framework 异常: 'OFFSET' 附近有语法错误。\r\n在 FETCH 语句中选项 NEXT 的用法无效。\r\n关键字 'AS' 附近有语法错误。

    在使用 EF 的时候,突然发现更新后在服务器中运行出错,异常信息主要包含以下信息: 'OFFSET' 附近有语法错误.\r\n在 FETCH 语句中选项 NEXT 的用法无效.\r\n关键字 'AS' ...

  5. [转]Entity Framework 异常: 'OFFSET' 附近有语法错误。\r\n在 FETCH 语句中选项 NEXT 的用法无效

    https://blog.csdn.net/weixin_34321977/article/details/85850064 在使用 EF 的时候,突然发现更新后在服务器中运行出错,异常信息主要包含以 ...

  6. Message "'OFFSET' 附近有语法错误。\r\n在 FETCH 语句中选项 NEXT 的用法无效。" 解决办法 EntityFrameworkCore

    由于新版的EntityFrameworkCore默认使用的是SqlServer2012或以上版本的Sql语法分页,来提高性能. 所以使用数据库的版本如果低于2012(如Sqlserver2008)需要 ...

  7. Sql语法高级应用之二:视图

    SQL CREATE VIEW 语句 什么是视图? 在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表. 视图包含行和列,就像一个真实的表.视图中的字段就是来自一个或多个数据库中的真实的表中 ...

  8. Sql语法高级应用之三:存储过程

    一.存储过程概述 SQL Server中的存储过程是使用T_SQL编写的代码段.它的目的在于能够方便的从系统表中查询信息,或者完成与更新数据库表相关的管理任务和其他的系统管理任务.T_SQL语句是SQ ...

  9. Sql语法高级应用之五:使用存储过程实现对明细多层次统计

    前言 前面章节我们讲到了存储过程的基础用法,本章则将一个在项目中实际应用的场景. 在项目中经常会存在这样的需求,例如需要对明细列表进行按组.按级别.按人等进行统计,如果在附带列表的查询条件,又如何实现 ...

随机推荐

  1. EasyUI汇总

    easyui combobox添加清除选项按钮 <input class="easyui-combobox" name="appType" data-op ...

  2. [RHEL7.1]关闭防火墙及SElinux

    一.关闭防火墙 1. 先查看防火墙状态 [root@bogon ~]# 1 systemctl status firewalld firewalld.service - firewalld - dyn ...

  3. 发布spring jar包, 报错

    org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Una ...

  4. Notepad++中的高级查找

      准备以下字符串用来演示 abcdeab cdeabcde abcd eabcde   基于扩展的查找 基于扩展的查找不能算是真正的正则表达式搜索,因此这种查找方式仅是提供了支持转义字符.主要常用的 ...

  5. 用TImageList动态画透明图片

    procedure TForm1.Button1Click(Sender: TObject); var bm : TBitmap; il : TImageList; begin bm := TBitm ...

  6. java普通类如何调用Spring的Service层?

    首先在Service层上面添加 @Service("myService") 然后,在main方法中调用,String[]中为配置文件,如下所示: ApplicationContex ...

  7. 08-SSH综合案例:前台用户模块:注册页面的前台JS校验

    这个是MyEclipse设置的问题 把设置去掉就没问题了. 你也可以在每一个input后面加个span来显示提示的信息.这些东西也要提交到后台,后台也是要对这些东西进行校验的.

  8. 关于ueditor与arcgis js api同用会报错的问题

    在ueditor与arcgis js api共用时,需要将ueditor\third-party\zeroclipboard\ZeroClipboard.js中的 if (typeof define ...

  9. Django基础模板案例

    想要用django  访问一个页面 同时传参数过去.在页面中接受参数 案例:附代码 #创建一个项目 项目名字是 yhl_test django-admin startproject yhl_test ...

  10. c语言define和typedef区别和使用

    define完全可以理解替换,typedef代表别名.听着差不多的意思,那2者区别在哪? 先来个简单例子查看基本使用. //define和typedef区别 #define DB double //替 ...