SQL Server 2005 中使用 Try Catch 处理异常
TRY...CATCH:SQL Server异常处理的优雅进化
如果你是SQL Server的老用户,一定对2005和2008版本引入的TRY...CATCH功能记忆犹新。它彻底改变了我们处理数据库错误的方式,把开发人员从繁琐的全局变量检查中解放了出来,让异常处理变得清晰、直观。今天,我们就来好好聊聊这个功能,看看它如何让我们的代码更加健壮。
免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
一、回顾:SQL Server 2000时代的异常处理
在TRY...CATCH出现之前,SQL Server 2000的世界里,错误处理是件挺“手工”的活儿。开发人员必须紧盯着那个全局变量@@ERROR,在每一条可能出错的DML语句(比如UPDATE、INSERT)之后,立刻检查它。你猜怎么着?因为这个变量会被紧接着的下一个数据库操作重置,所以检查动作必须争分夺秒,绝不能延迟。
看看下面这个典型的存储过程例子,你就能感受到那种“步步惊心”的编码风格:
CREATE PROC usp_AccountTransaction
@AccountNum INT,
@Amount DECIMAL
AS
BEGIN
BEGIN TRANSACTION --开始一个事务
UPDATE MyChecking SET Amount = Amount - @Amount
WHERE AccountNum = @AccountNum
IF @@ERROR != 0 --在每个DML语句后立即检查@@ERROR
BEGIN
ROLLBACK TRANSACTION --如果出错,回滚事务
RETURN
END
ELSE
BEGIN
UPDATE MySa vings SET Amount = Amount + @Amount
WHERE AccountNum = @AccountNum
IF @@ERROR != 0 --再次检查@@ERROR
BEGIN
ROLLBACK TRANSACTION --如果出错,回滚事务
RETURN
END
ELSE
BEGIN
COMMIT TRANSACTION --全部成功,最终提交事务
RETURN
END
END
END
GO
这种方式的问题显而易见:代码被大量重复的错误检查逻辑所淹没,业务逻辑本身反而显得支离破碎。维护起来,着实需要点耐心。
二、进化:SQL Server 2005引入的TRY...CATCH
SQL Server 2005带来的TRY...CATCH,就像是给T-SQL语言注入了一股现代编程的清风。它的语法对于任何熟悉C#或Ja va的开发者来说都倍感亲切,这种跨语言的一致性,本身就是一次巨大的体验提升。当然了,如果你怀念旧方式,@@ERROR依然被支持。
1. 核心语法结构
它的结构非常清晰,一看就懂:
BEGIN TRY
-- 可能抛出异常的代码块
Try Statement 1
Try Statement 2
...
END TRY
BEGIN CATCH
-- 异常处理代码块
Catch Statement 1
Catch Statement 2
...
END CATCH
当TRY块中的任何语句发生错误时,控制流会立即跳转到CATCH块,剩下的TRY块代码将被跳过。这就像为你的代码逻辑安装了一个安全网。
2. 强大的错误信息函数
进入CATCH块后,你就可以调用一系列专属的系统函数来“诊断”刚才发生的错误,这比昔日的@@ERROR那一丁点信息强太多了:
ERROR_NUMBER() – 返回错误号。
ERROR_SEVERITY() – 返回错误严重级别。
ERROR_STATE() – 返回错误状态号。
ERROR_PROCEDURE() – 返回出错的存储过程名。
ERROR_LINE() – 返回发生错误的具体行号。
ERROR_MESSAGE() – 返回完整的错误消息文本。
来个小例子感受一下:
BEGIN TRY
SELECT GETDATE()
SELECT 1/0 --经典的除零错误!
END TRY
BEGIN CATCH
SELECT 'There was an error! ' + ERROR_MESSAGE()
RETURN
END CATCH;
3. 事务处理的优雅写法
有了TRY...CATCH,处理事务中的错误就变得异常优雅。看,之前那个冗长的存储过程,现在可以写得如此简洁:
ALTER PROC usp_AccountTransaction
@AccountNum INT,
@Amount DECIMAL
AS
BEGIN
BEGIN TRY -- 开启Try块
BEGIN TRANSACTION -- 开始事务
UPDATE MyChecking SET Amount = Amount - @Amount
WHERE AccountNum = @AccountNum
UPDATE MySa vings SET Amount = Amount + @Amount
WHERE AccountNum = @AccountNum
COMMIT TRAN -- 一切顺利,提交事务!
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRAN -- 捕获到异常,回滚事务
-- 你还可以用RAISEERROR()将异常再次抛出,通知调用者
RAISERROR(ERROR_MESSAGE(), ERROR_SEVERITY(), 1)
END CATCH
END
GO
代码的逻辑主干一下子清晰了:TRY块里专注业务,CATCH块里统一收拾残局。这才是现代化错误处理该有的样子。
三、实战:构建一个完整的错误日志系统
理论说得再好,不如动手实践。我们来看一个更实际的场景:如何利用TRY...CATCH构建一个错误日志记录系统。
首先,创建一张表来存放错误日志:
CREATE TABLE ErrorLog(errNum INT,ErrSev NVARCHAR(1000),ErrState INT,ErrProc NVARCHAR(1000),ErrLine INT, ErrMsg NVARCHAR(2000))
接着,创建一个存储过程来自动化日志记录工作。这个过程会在被调用时,捕获当前错误上下文并存入日志表:
CREATE PROCEDURE ErrorLog
AS
SELECT ERROR_NUMBER() AS ErrNum,ERROR_SEVERITY()AS ErrSev,ERROR_STATE() AS ErrState,ERROR_PROCEDURE() AS ErrProc,ERROR_LINE()AS ErrLine,ERROR_MESSAGE()AS ErrMsg
INSERT
INTO ErrorLog
VALUES(ERROR_NUMBER(),ERROR_SEVERITY(),ERROR_STATE(),ERROR_PROCEDURE(),ERROR_LINE(),ERROR_MESSAGE())
GO
现在,我们编写一个业务存储过程,并在其中使用TRY...CATCH和这个日志工具:
USE [Your_Test]
GO
ALTER PROCEDURE [dbo].[getTodayBirthday]
AS
BEGIN TRY
declare @today datetime;
SET @today = GETDATE(); -- 获取今天日期
DECLARE @day VARCHAR(2);
SET @day =REPLACE(DAY(@today),0,'');
DECLARE @month VARCHAR(2) ;
SET @month = REPLACE(month(@today),0,'');
DECLARE @year VARCHAR(4);
SET @year = YEAR(@today);
SELECT * FROM dbo.UserInfo
WHERE REPLACE(DAY(CONVERT(DATETIME,Birthday )),0,'') =@day
AND REPLACE(MONTH(CONVERT(DATETIME,Brithday)),0,'')=@month
AND Birthday IS NOT NULL
END TRY
BEGIN CATCH
EXEC ErrorLog -- 一旦出错,立即调用日志过程保存证据
END CATCH
需要特别注意的是,ERROR_NUMBER(), ERROR_SEVERITY() 等这一系列错误函数,只能在CATCH块的作用域内使用。在TRY块或CATCH块之外调用它们,是获取不到值的。
总的来说,从@@ERROR到TRY...CATCH,SQL Server的异常处理完成了一次漂亮的升级。它不仅让代码更易写、易读,更重要的是,它为构建健壮、可维护的数据库应用提供了坚实的基础设施。如果你的系统还没用上这个特性,现在是时候尝试一下了。
相关攻略
TRY CATCH:SQL Server异常处理的优雅进化 如果你是SQL Server的老用户,一定对2005和2008版本引入的TRY CATCH功能记忆犹新。它彻底改变了我们处理数据库错误的方式,把开发人员从繁琐的全局变量检查中解放了出来,让异常处理变得清晰、直观。今天,我们就来好好聊
3月26日消息,心玮医疗-B(HK6609)发布截至2025年12月31日止年度业绩,该集团取得收益4 08亿元(人民币,下同),同比增长46 9%;毛利2 9亿元,同比增长59 3%;研发成本40
由于开发者的主观原因,java程序中可能会存在一些漏洞,从而影响程序的正常运行。因此,我们可以通过异常处理机制来应对这些问题。1、 首先,我们需要编写一段代码。2、 运行这段代码时
c++++中的异常处理机制有助于增强程序的健壮性,降低程序崩溃的可能性。下面介绍如何正确使用c++的异常处理功能。1、假设我们编写了一个用于执行除法运算的程序。2、当程序成功编译后
编程过程中难免会遇到异常情况,所谓异常就是在程序运行时发生的事件,这种事件会影响程序的正常执行。如果在python中出现了未被捕获和处理的异常,程序就会终止运行,因此对异常进行有效
热门专题
热门推荐
2026年4月2日,一场始于订单的“双向奔赴” 汽车圈最近上演了一出颇有温度的品牌互动,起因是一张来自社交平台的购车订单。一位原奥迪车主公开晒出了小米SU7的订单截图,并向相关负责人致以问候。这原本只是一条个人动态,却没承想,引发了一连串超出预期的友好回应。 消息传出后,上汽奥迪的反应堪称迅速且巧妙
特斯拉2026年Q1财报解读:业绩稳健增长,自动驾驶与机器人战略加速落地 2026年第一季度,特斯拉再次向市场展示了其强劲的发展动能。在全球电动汽车市场,特斯拉产量成功突破40 8万辆,实现同比12 7%的稳健增长;同期交付量达到35 8万辆,同比增长6 5%。与此同时,特斯拉储能业务表现突出,总装
四月一日,沙盒游戏我的世界推出一次特别更新,引发广泛关注 话说回来,四月的第一天,经典沙盒游戏《我的世界》,就整了个“大活儿”。一项听起来颇有碘伏性的设计调整,在社区内炸开了锅:游戏直接移除了沿用已久的仓库系统,改为所有物品都能随手放在地面,想用的时候捡起来就行。 仓库功能向来是此类建造型游戏的核心
巨鲸再出手:千万美元级ETH悄然离场 市场总是静水深流。就在今天,链上数据捕捉到一笔值得玩味的动向。根据链上分析师Onchain Lens的监测,大约三小时前,一个地址尾号为“24d4”的巨鲸,从知名交易所Kraken一口气提取了4,472枚ETH。按当前市价估算,这笔资产价值接近一千万美元。 这可
京东京造再推黄金配件新品:磁吸支架以亲民价格亮相 关注京东京造的朋友一定还记得此前推出的黄金手机壳,因其独特设计与高纯度金材质引发了不少讨论。如今品牌再度升级,带来了一款更贴近日常使用的“轻量化”黄金配件——黄金气囊手机磁吸支架,进一步降低了黄金数码配件的入手门槛。 产品解析:含金量与设计亮点 这款





