SQL Server 2005 中使用 Try Catch 处理异常

TRY...CATCH是Sql Server 2005/2008令人印象深刻的新特性.提高了开发人员异常处理能力.没有理由不尝试一下Try.. Catch功能.

* TRY 块 - 包含可能产生异常的代码或脚本
* CATCH 块 - 如果TRY块出现异常,代码处理流将被路由到CATCH块.在这里你可以处理异常,记录日志等.
Sql Server中的Try Catch和C#,JAVA等语言的处理方式一脉相承.这种一致性才是最大的创新之处.

一、SQL SERVER 2000中异常处理

CREATE PROC usp_AccountTransaction 

  @AccountNum INT, 

  @Amount DECIMAL 

AS 

BEGIN 

  BEGIN TRANSACTION --beginning a transaction.. 

    UPDATE MyChecking SET Amount = Amount - @Amount 

      WHERE AccountNum = @AccountNum 

    IF @@ERROR != 0 --check @@ERROR variable after each DML statements.. 

    BEGIN 

      ROLLBACK TRANSACTION --RollBack Transaction if Error.. 

      RETURN 

    END 

    ELSE 

    BEGIN 

      UPDATE MySavings SET Amount = Amount + @Amount 

        WHERE AccountNum = @AccountNum 

      IF @@ERROR != 0 --check @@ERROR variable after each DML statements.. 

      BEGIN 

        ROLLBACK TRANSACTION --RollBack Transaction if Error.. 

        RETURN 

      END 

      ELSE 

      BEGIN 

        COMMIT TRANSACTION --finally, Commit the transaction if Success.. 

        RETURN 

      END 

    END 

END 

GO 

上面是Sql server 2000的一个存储过程,在每个数据库操作之后立即必须检查@@ERROR,进行Commit / RollBack该事务.
Sql server 2000中监测错误,只能通过监测全局遍历 @@ERROR.由于@@ERROR会被下一个数据库操作所覆盖. 所以在每次操作完后必须立即监测.

二、SQL SERVER 2005中异常处理

TRY...CATCH是SQL Server 2005提供的更具有可读性的语法.每个开发人员都熟悉这种写法.SQL Server 2005仍然支持@@ERROR这种用法.

1.try catch语法:

BEGIN TRY 

  Try Statement 1 

  Try Statement 2 

  ... 

  Try Statement M 

END TRY 

BEGIN CATCH 

  Catch Statement 1 

  Catch Statement 2 

  ... 

  Catch Statement N 

END CATCH 

2.获得错误信息的函数表:

下面系统函数在CATCH块有效.可以用来得到更多的错误信息:

函数 描述

ERROR_NUMBER() 返回导致运行 CATCH 块的错误消息的错误号。
ERROR_SEVERITY() 返回导致 CATCH 块运行的错误消息的严重级别
ERROR_STATE() 返回导致 CATCH 块运行的错误消息的状态号
ERROR_PROCEDURE() 返回出现错误的存储过程名称
ERROR_LINE() 返回发生错误的行号
ERROR_MESSAGE() 返回导致 CATCH 块运行的错误消息的完整文本

简单示例:

BEGIN TRY 

  SELECT GETDATE() 

  SELECT 1/0--Evergreen divide by zero example! 

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 --Start the Try Block.. 

    BEGIN TRANSACTION -- Start the transaction.. 

      UPDATE MyChecking SET Amount = Amount - @Amount 

        WHERE AccountNum = @AccountNum 

      UPDATE MySavings SET Amount = Amount + @Amount 

        WHERE AccountNum = @AccountNum 

    COMMIT TRAN -- Transaction Success! 

  END TRY 

  BEGIN CATCH 

    IF @@TRANCOUNT > 0 

      ROLLBACK TRAN --RollBack in case of Error 

    -- you can Raise ERROR with RAISEERROR() Statement including the details of the exception 

    RAISERROR(ERROR_MESSAGE(), ERROR_SEVERITY(), 1) 

  END CATCH 

END 

GO

三、实例讲解

创建错误日志表:

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
/****** Object: StoredProcedure [dbo].[getTodayBirthday]
    Script Date: 05/17/2010 15:38:46
    Author:jinho
    Desc:获取当天生日的所有人
    ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
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
 ErrorLog --调用上面的存储过程,保存错误日志
 END CATCH

说明:ERROR_NUMBER(),ERROR_SEVERITY(),ERROR_STATE(),ERROR_PROCEDURE(),ERROR_LINE(),ERROR_MESSAGE() 这几个函数只能用在Catch里面!

(0)

相关推荐

  • SQL Server 2005附加数据库时Read-Only错误的解决方案

    SQL Server 2005附加数据库文件时出现了Read-Only错误,附加的时候,系统提示mdf文件为只读,可是打开文件属性,这个属性不为只读.该怎么解决呢?本文我们就介绍了这一解决方案,接下来就让我们来一起了解一下吧. 两种解决方法如下: 1.重新打开数据库软件,在登录认证框那里选择:Windows authentication进行登录.然后再附加数据库,这时附加的就没有Read-Only了. 2.在*.mdf文件的属性里,找到"安全"页,然后把里面所有的"组或用户名

  • SQL Server 2005安装配置方法图文教程 完美兼容Win7所有版本

    印象中,以前电脑不发达,自身编程经历不多的时候,由于Microsoft SQL Server版本众多,在不同版本的windows下必须要求装相应版本的SQL Server,否则有可能出现兼容性的问题,装个Microsoft SQL Server总是非常费劲,装完之后用起来,由于Microsoft SQL Server还需要比较多的运行资源,玩起来卡得不要不要的,最后Microsoft SQL Server给我留下了很难用很难消化的形象. 不过现在看来,Microsoft SQL Server的S

  • Microsoft Sql server2005的安装步骤图文详解及常见问题解决方案

    一:安装sql server 2005过程中出现如下问题:"选择的功能中没有任何功能可以安装或升级": 解决方案:Microsoft SQL Server 2005→配置工具→SQL配置管理器→SQL Server 2005服务→右边的两个服务启动SQL Server FullTest Search() 和服务SQl Sever(计算机名) 二:无法将数CLSID写入\Software\Classes\PROTOCOLS\Handler\ms-help. 解决办法:退出电脑安全软件 三

  • 详解删除SQL Server 2005 Compact Edition数据库

    详解删除SQL Server 2005 Compact Edition数据库 本主题将介绍如何删除 Microsoft SQL Server 2005 Compact Edition (SQL Server Compact Edition) 数据库.由于 SQL Server Compact Edition 数据库是文件系统中的文件,因此需要通过删除文件来删除 SQL Server Compact Edition 数据库. 删除 SQL Server Compact 数据库 调用 System.

  • SQL Server 2005 Management Studio Express企业管理器将英文变成简体中文版的实现方法

    看到这个文章肯定一点就是你把sql没有装到C盘里,呵呵不用怕看下面 在安装的时候要注意:在安装SQL Server 2005 Express时候需要将公共组件安装在C盘然后再安装SQL Server Management Studio Express中文版本,若将SQL Server 2005 Express时候需要将公共组件安装在其他逻辑盘上再安装SQL Server Management Studio Express时候中文版本时SQL Server Management Studio Ex

  • SQLServer 2008数据库降级到2005低版本

    由于目前还广泛使用着SQLServer2000,很多公司又想使用新的SQLServer,从而直接[分离/附加]或者[备份/还原]数据库,在不同版本之间存放.往往就会遇到版本不兼容的问题.前几天遇到了从我本机2008R2上备份的一个数据库还原到2008上面时报错: 从运行版本10.50.2500(2008R2是10.50)和10.00.1600(2008是10.00)中可以看出这个版本不兼容问题,大部分情况下,从低版本升级到高版本,只要不是跨度太大,如2000升级到2012,都不会怎么报错.除非使

  • SQL2005查看死锁存储过程sp_who_lock

    下面是我整理的监控sql server数据库,在性能测试过程中是否出现死锁.堵塞的SQL语句,还算比较准备,留下来备用. 调用方法:选中相应的数据库,执行exec sp_who_lock USE [master] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE procedure [dbo].[sp_who_lock] as begin declare @spid int, @bl int, @intTransactionCo

  • SQL Server 2005 中使用 Try Catch 处理异常

    TRY...CATCH是Sql Server 2005/2008令人印象深刻的新特性.提高了开发人员异常处理能力.没有理由不尝试一下Try.. Catch功能. * TRY 块 - 包含可能产生异常的代码或脚本 * CATCH 块 - 如果TRY块出现异常,代码处理流将被路由到CATCH块.在这里你可以处理异常,记录日志等. Sql Server中的Try Catch和C#,JAVA等语言的处理方式一脉相承.这种一致性才是最大的创新之处. 一.SQL SERVER 2000中异常处理 CREAT

  • SQL Server 2005中更改sa的用户名的方法

    修改数据库SA账号名称的代码如下: 复制代码 代码如下: Alter LOGIN sa DISABLE Alter LOGIN sa WITH NAME = [systemAccount] "systemAccount" 为SA的新名称,执行完成后刷新一下右侧登录名即可看到修改成功的账号名称. SQL Server 2005修改sa用户密码的方法图文版 一.修改SQL Server 2005中sa用户密码的方法 1. 点击"开始 - 所有程序 - Microsoft SQL

  • SQL Server 2005中的外联结用法

    SQL Server 2005中的外联结用法一: 有两个表:学生表,学生选课表,表中数据为: 学生表: 学生选课表: 要查看所有学生的选课信息, 标准的SQL语句,外联结语句为 use stu_course select L.sno,sname,ssex,sage,sdept,cno,grade from student L,sc where L.sno=sc.sno(*) 理论上的结果为: 但是,在SQLServer2005中运行会出现错误,错误提示为: 消息 102,级别 15,状态 1,第

  • 在SQL Server 2005中创建CLR存储过程的详细介绍

    在2005之前的版本创建存储过程都是在数据库里面写Transact-SQL语言实现的,不过现在SQL Server 2005支持用其他面向对象的语言编写CLR存储过程了,关于这样做的好处,官方有很多解释了,这里就直接说明实现方法了. 假设服务器里面有个test数据库,数据库有个架构user,还有一个表test1,然后有个sql登陆用户叫test_user,将这个用户设置成VS2005里面数据库连接的登陆用户. 在VS2005中创建一个项目,类别是SQL Server数据库项目,然后往项目里面添加

  • SQL server 2005中设置自动编号字段的方法

    如果希望重新定义在表中添加新记录时该列中自动生成并存储于列中的序列号,则可以更改该列的标识属性.在每个表中只能设置一个列的标识属性. 具有标识属性的列包含系统生成的连续值,该值唯一地标识表中的每一行(例如,雇员标识号).在包含标识列的表中插入值时,Microsoft SQL Server 将基于上一次使用的标识值(标识种子属性)和在创建列时指定的增量值(标识增量属性)自动生成下一个标识符. 注意: 只能为不允许空值且数据类型为 decimal.int.numeric.smallint.bigin

  • SQL Server 2005 中做全文检索的方法分享

    /*打开全文索引支持,启动SQL Server的全文搜索服务 */ execute sp_fulltext_database 'enable' /*创建全文目录*/ EXEC SP_FULLTEXT_CATALOG 'FT_testData','CREATE' /*建立全文索引数据元*/ EXEC sp_fulltext_table 'Hc_Book_Book','CREATE','FT_testData','PK_Hc_Book_BookInfo' /*添加支持全文索引的列名*/ EXEC s

  • Sql Server 2005中查询用分隔符分割的内容中是否包含其中一个内容

    今天做项目遇到一个问题, 有产品分类A,B,C顶级分类, 期中A下面有a1,a2,a3子分类. 但是a1可能共同属于A和B,然后我的数据库是这样设计的       id           name         parnet   1 A 0 2 B 0 3 a1 1,2 如果想要查询A的所有子类的话就要查询parent中包含1的,所以就萌生了这个办法.呵呵, 暂时没什么好办法,欢迎拍砖~~ 另外,这个东西我想弄成bool返回值的,哪位兄弟会的希望帮忙解决一下.... 复制代码 代码如下: S

  • sql server 2005中使用with实现递归的方法

    复制代码 代码如下: WITH fw_requestion_note_temp(old_apply_id) AS ( --取根节点放入临时表 SELECT old_apply_id FROM fw_requestion_note --WHERE old_apply_id = 'e741470e-8b5c-4f91-9b03-c7474d103aef' --根据已取到的数据递归取其字节点的数据 UNION ALL SELECT fw.old_apply_id FROM fw_requestion_

  • JDBC连接Sql Server 2005总结

    1.准备工作: 准备相关的软件(Eclipse除外,开源软件可以从官网下载) <1>.Microsoft SQL server 2005 Express Edition 下载地址:http://download.microsoft.com/download/0/9/0/09020fab-d2c3-4a8c-b9e0-db53a7a30ae8/SQLEXPR_CHS.EXE <2>.SQL Server Management Studio 下载地址:http://www.micros

  • SQL Server存储过程中编写事务处理的方法小结

    本文实例讲述了SQL Server存储过程中编写事务处理的方法.分享给大家供大家参考,具体如下: SQL Server中数据库事务处理是相当有用的,鉴于很多SQL初学者编写的事务处理代码存往往存在漏洞,本文我们介绍了三种不同的方法,举例说明了如何在存储过程事务处理中编写正确的代码.希望能够对您有所帮助. 在编写SQL Server 事务相关的存储过程代码时,经常看到下面这样的写法: begin tran update statement 1 ... update statement 2 ...

随机推荐