SQL Server错误严重性级别和异常处理

关于SQL Server的错误严重性级别的说明,强烈认真看一下下面的两个链接

脱机帮助

ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.zh-CHS/sqlerrm9/html/3e7f5925-6edd-42e1-bf17-f7deb03993a7.htm

在线帮助

http://technet.microsoft.com/zh-cn/library/ms164086.aspx

简而言之,SQL Server的错误严重性分为三个等级

1. 轻微错误 :严重性级别为0-10

2. 中等错误 :严重性级别为11-19

3. 严重错误 :严重性级别为20-25

SQL Server保存的所有错误消息是可以通过检索sys.messages这个视图来查看的,如下

为什么需要说这个呢?是因为我们需要知道不同的错误严重性级别所导致的行为是不一样的

1. 轻微错误 :严重性级别为0-10  ==》默认情况下不会给客户程序发送错误消息,继续工作。也就是说它无法被CATCH到

2. 中等错误 :严重性级别为11-19 ==》能够被CATCH到(不管是在T-SQL里面还是在客户程序里面)

3. 严重错误 :严重性级别为20-25 ==》SQL Server将强制把连接关掉。很显然这也不可能被CATCH到

关于在T-SQL中使用TRY...CATCH处理异常,请参考下面的链接

http://technet.microsoft.com/zh-cn/library/ms179296.aspx

关于在客户端程序中处理异常,分两种情况

1. 对于错误严重性级别在11-19之间的,能够被TRY...CATCH到SQLException类型,然后可以对其进行处理

http://msdn.microsoft.com/zh-cn/library/system.data.sqlclient.sqlexception(VS.80).aspx

2. 对于错误严重性级别在0-10之间的系统错误,或者通过PRINT语句发出的消息,或者通过RAISERROR语句发出的错误,如果需要在客户程序里面处理,那么应该编写Connection对象的InfoMessage事件

http://msdn.microsoft.com/zh-tw/library/a0hee08w.aspx

关于infoMessage事件,因为它可以接受PRINT语句的输出消息,所以也有朋友用它来跟踪存储过程的进度等等,下面就有一个范例

http://www.cnblogs.com/hackzai/archive/2005/04/07/133635.html

还有一个属性很有意思,FireInfoMessageEventOnUserErrors 。这个属性为true,那么除了0-10的会被该事件处理,11-19的也可以通过该事件来处理,而不需要用TRY...CATCH

http://msdn.microsoft.com/zh-tw/library/system.data.sqlclient.sqlconnection.fireinfomessageeventonusererrors.aspx

下面是一个例子

private void btTest_Click(object sender, EventArgs e)
{
    using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString))
    {
       conn.FireInfoMessageEventOnUserErrors = true;
        conn.InfoMessage += new SqlInfoMessageEventHandler(conn_InfoMessage);
        SqlCommand cmd = conn.CreateCommand();
        cmd.CommandText = "DROP TABLE TABLE1"; //这里我是故意让它出错,因为表不存在。由于前面设置了FireInfoMessageEventOnUserErrors为true,所以会自动由infoMessage事件处理
        conn.Open();
        cmd.ExecuteNonQuery();
        cmd.CommandText = "RAISERROR(‘This is the message from the RAISERROR statement‘, 10, 1)";
        cmd.ExecuteNonQuery();
        conn.Close();
    }

}

void conn_InfoMessage(object sender, SqlInfoMessageEventArgs e)
{
    MessageBox.Show(string.Format("Source:{0},Message:{1}", e.Source, e.Message));
}

值得注意的是,不管是SQLException还是InfoMessage中的事件参数SqlInfoMessageEventArgs,它们都包含一个Errors的集合,里面包含了所有的错误实例。一个完善的异常处理,应该遍历它们。例如下面这样

public static void ShowSqlException(string connectionString)
{
    string queryString = "EXECUTE NonExistantStoredProcedure";
    StringBuilder errorMessages = new StringBuilder();
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        SqlCommand command = new SqlCommand(queryString, connection);
        try
        {
            command.Connection.Open();
            command.ExecuteNonQuery();
        }
        catch (SqlException ex)
        {
            for (int i = 0; i < ex.Errors.Count; i++)
            {
                errorMessages.Append("Index #" + i + "\n" +
                    "Message: " + ex.Errors[i].Message + "\n" +
                    "LineNumber: " + ex.Errors[i].LineNumber + "\n" +
                    "Source: " + ex.Errors[i].Source + "\n" +
                    "Procedure: " + ex.Errors[i].Procedure + "\n");
            }
            Console.WriteLine(errorMessages.ToString());
        }
    }
}

时间: 2024-10-21 17:05:07

SQL Server错误严重性级别和异常处理的相关文章

SQL Server错误收集#6

错误#1 22:26 2014-7-30 重置连接数对实例->属性->连接->最大并发连接数不是特别理解,昨天下午心血来潮,把连接数改成1,不断开启新的查询窗口,并没有按预想的出错(当时没有重启数据库服务).今天早上打开电脑,打开对象资源管理器,连接到服务器时报错. 查看ERRORLOG,错误信息很明显,超过最大并发连接数. 2014-07-30 09:35:37.12 登录 错误: 17809,严重性: 20,状态: 3. 2014-07-30 09:35:37.12 登录 Could

SQL Server错误收集#3

错误#1 16:50 2014-5-20安装好数据库(08R2),启动数据库代理服务失败,当时也没在意.后来装上SQL12,再次启动数据库代理依旧失败.不能再得过且过,该找找具体原因了.查看SQLAGENT代理日志: 2014-05-20 16:51:33 - ? [100] Microsoft SQLServerAgent 版本 11.0.2100.60 (内部版本号 x86 unicode 零售): 进程 ID 3076 2014-05-20 16:51:33 - ? [495] SQL S

SQL Server:错误处理及事务控制

目录: 解读错误信息 RAISERROR THROW 实例 使用 @@ERROR 使用 XACT_ABORT 使用TRY/CATCH 现实中的事务语句 删除 更新 银行取钱 解读错误信息 Msg 547, Level 16, State 0, Line 11 The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Products_Categories". The conflict occurred in

SQL Server 2016 行级别权限控制

原文:SQL Server 2016 行级别权限控制 背景 假如我们有关键数据存储在一个表里面,比如人员表中包含员工.部门和薪水信息.只允许用户访问各自部门的信息,但是不能访问其他部门.一般我们都是在程序端实现这个功能,而在sqlserver2016以后也可以直接在数据库端实现这个功能. 解决 安全已经是一个数据方面的核心问题,每一代的MS数据库都有关于安全方面的新功能,那么在Sql Server 2016,也有很多这方面的升级,比如'Row Level Security', 'Always E

sql server 错误日志errorlog

一 .概述 SQL Server 将某些系统事件和用户定义事件记录到 SQL Server 错误日志和 Microsoft Windows 应用程序日志中. 这两种日志都会自动给所有记录事件加上时间戳. 使用 SQL Server 错误日志中的信息可以解决SQL Server的相关问题. 查看 SQL Server 错误日志可以确保进程(例如,备份和还原操作.批处理命令或其他脚本和进程)成功完成. 此功能可用于帮助检测任何当前或潜在的问题领域,包括自动恢复消息(尤其是在 SQL Server 实

系统断定检查已失败。有关详细信息,请查看 SQL Server 错误日志

[1]报错信息 运行删除时报错 操作的删除语句: IF OBJECT_ID('tempdb..#temp_Robot') IS NOT NULL DROP TABLE #temp_Robot CREATE TABLE #temp_Robot(UserID INT NOT NULL PRIMARY KEY) select * from #temp_robot INSERT INTO #temp_Robot SELECT UserID FROM Db_Tank..Sys_Users_Order WH

SQL Server 事务隔离级别详解

原文:SQL Server 事务隔离级别详解 标签: SQL SEERVER/MSSQL SERVER/SQL/事务隔离级别选项/设计数据库事务级别 SQL 事务隔离级别 概述 隔离级别用于决定如果控制并发用户如何读写数据的操作,同时对性能也有一定的影响作用. 步骤 事务隔离级别通过影响读操作来间接地影响写操作:可以在回话级别上设置事务隔离级别也可以在查询(表级别)级别上设置事务隔离级别.事务隔离级别总共有6个隔离级别:READ UNCOMMITTED(未提交读,读脏),相当于(NOLOCK)R

SQL SERVER错误:已超过了锁请求超时时段。 (Microsoft SQL Server,错误: 1222)

在SSMS(Microsoft SQL Server Management Studio)里面,查看数据库对应的表的时候,会遇到"Lock Request time out period exceeded.(Microsoft SQL Server, 错误1222)",对应的中文错误提示为"已超过了锁请求超时时段. (Microsoft SQL Server,错误: 1222)",如下截图所示,不管是用一般权限的账号还是具有sysadmin角色的登录名都是如此. 这

sql连接错误(Microsoft SQL Server,错误:2)

昨天用SQL语句建表的时候写了一段代码,对于代码的逻辑和内容我不太肯定对不对,反正是毫不犹豫的让它执行了,过程中出现好几个错误,当时没有太在意,想着大不了出错了再重写一个,结果--玩坏了,从昨天到现在十几个小时,SQL Server毫无商量的给我罢工了!于是乎,漫长的"寻错"之路开始了. 先看下出错信息: 1.通过以往经验我先打开了SQL Server配置工具-->配置管理器,检查里边的协议是否开启,就在这时我又犯了一个错误.因为不知道那些协议到底是什么意思,索性干脆都启用了,结