ADO.NET异常的处理方法
private void btnADOEx1_Click(object sender, EventArgs e)
{
SqlConnection cn = new
SqlConnection(@"server=localhost;Integrated Security=SSPI;database=Northwind");
SqlCommand cmd = cn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
try
{
cn.Open();
SqlDataReader dr = cmd.ExecuteReader();
dr.Close();
cn.Close();
}
catch (SqlException e2)
{
string strEx;
strEx = "Source:" + e2.Source;
strEx = strEx + "/n" + "Exception Message:" + e2.Message;
MessageBox.Show(strEx, "Database Exceptin");
cn.Close();
}
//catch (System.Exception e3)
//{
// string strEx;
// strEx = "Source:" + e3.Source;
// strEx = strEx + "/n" + "Exception Message:" + e3.Message;
// MessageBox.Show(strEx, "Non-Database Exception");
//}
finally
{
if (cn.State == ConnectionState.Open)
{
MessageBox.Show("Finally closing the connection", "Finall block");
}
}
}
private void btnADOEx2_Click(object sender, EventArgs e)
{
SqlConnection cn = new
SqlConnection(@"server=localhost;Integrated Security=SSPI;database=Northwind");
SqlCommand cmd = cn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sp_Selec_AllEmployees";
try
{
cn.Open();
SqlDataReader dr = cmd.ExecuteReader();
string strName = dr.GetValue(20).ToString();
dr.Close();
}
//显示异常的来源,消息,踪迹
catch (InvalidOperationException e1)
{
string strEx;
strEx = "Source:" + e1.Source;
strEx = strEx + "/n" + "Message:" + e1.Message;
strEx = strEx + "/n" + "/n";
strEx = strEx + "/n" + "Stack Trae:" + e1.StackTrace;
MessageBox.Show(strEx, "Secfiic Exception");
}
catch (System.Data.SqlClient.SqlException e2)
{
string strEx;
strEx = "Source:" + e2.Source;
strEx = strEx + "/n" + "Message:" + e2.Message;
MessageBox.Show(strEx, "Database Exception");
}
catch (System.Exception e3)
{
string strEx;
strEx = "Source:" + e3.Source;
strEx = strEx + "/n" + "Message:" + e3.Message;
MessageBox.Show(strEx, "Gneric Exception");
}
finally
{
if (cn.State == ConnectionState.Open)
{
MessageBox.Show("closed finally");
cn.Close();
}
}
}
}
}
数据庫异常的处理方法
1)RAISERRO异常
调用一个有RISEERROR语句的存储过程
SQL Server数据庫返回警告或错误时,抛出SqlException类型的异常。以下是有关异常信息的属性:
Class 异常级别 1到10是信息错误,11到16是用户级,17到25是软件或硬件错误。20级或以上关闭连接。
HelpLink与异常相关的帮助文件
Server生成异常的计算机名称
Source生成异常的提供者称
State SQL Server中的数值错误代码,代表 异常,警告等。
Number 标识异常类型的数值
LineNumver得到生成异常Transact-SQL批命令或存储过程内的行号
现在,让我们看一下C#中处理SQL错误。
Orders表中的定单超过10时,将使用这个语句引发错误:
if @OrdersCount>10
RAISERROR('Orders Count is greater than 10-Notify the Business Manager',16,1)
在这个RAISEERROR语句中,我们使用严重性级别16,任意状态号1,同时提供字符串。编写的RAISERROR语句含有消息字符串时,自动使错误号成为50000。SQL Server使用RAISERROR引发错误时,使用预定义的消息词典给出对应的错误号。可查阅MSDN的RAISERROR来确定。
它会在应用程序执行过程中抛出异常:
try
{
cn.Open();
cmd.ExecuteNonQuery();//执行存储过程,引发并抛出存储过程编写的异常语句
}
存储过程编写如下:
CREATE PROC sp_DBException_1
AS
SET NOCOUNT ON
DECLARE @OrdersCount int
SELECT @OrdersCount=count(*)
FROM Orders
if @OrdersCount>10
RAISERROR('Orders Count is greater than 10-Notify the Business Manager',16,1)
RETURN
GO
完整代代码如下:
private void brnDBEx1_Click(object sender, EventArgs e)
{
SqlConnection cn = new
SqlConnection(@"server=localhost;Integrated Security=SSPI;database=Northwind");
SqlCommand cmd = cn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sp_DBException_1";//设置存储过程名称
try
{
cn.Open();
cmd.ExecuteNonQuery();//执行存储过程,引发异常
}
catch (SqlException e2)
{
string strEx;
strEx = "Source:" + e2.Source;//提供者名称
strEx = strEx + "/n" + "Number:" + e2.Number.ToString();//异常类型的数值
//异常文本(存储过程中的Orders Count is greater than 10-Notify the Business Manager)
strEx = strEx + "/n" + "Message:" + e2.Message;
strEx = strEx + "/n" + "Class:" + e2.Class.ToString();//级别
strEx = strEx + "/n" + "Procedure:" + e2.Procedure.ToString();//存储过程名称
strEx = strEx + "/n" + "Line Number:" + e2.LineNumber.ToString();//行号
strEx = strEx + "/n" + "Server:" + e2.Server.ToString();//计算机名
MessageBox.Show(strEx, "Database Exception");
}
catch (System.Exception e3)
{
string strEx;
strEx = "Source:" + e3.Source;
strEx = strEx + "/n" + "Error Message:" + e3.Message;
MessageBox.Show(strEx, "General Exception");
}
finally
{
cn.Close();
}
2)存储过程
在执行存储过程时,遇到错误。
现在让我们看存储过程中的语句遇到错误时会出现什么结果。我们创建一个存储过程,该过程将完成非法的INSERT操作,然后将从SqlException 对象中提取信息:
创建名为sp_DBException_2的存储过程:
CREATE PROC sp_DBException_2
AS
SET NOCOUNT ON
INSERT INTO Employees(EmployeeId,FirstName) VALUES(50,'Cinderella')
RETURN
处理代码:
private void brnDBEx2_Click(object sender, EventArgs e)
{
SqlConnection cn = new
SqlConnection(@"server=localhost;Integrated Security=SSPI;database=Northwind");
SqlCommand cmd = cn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sp_DBException_2";//设置存储过程名称
try
{
cn.Open();
cmd.ExecuteNonQuery();//执行存储过程,引发异常
}
catch (SqlException e2)
{
string strEx;
strEx = "Source:" + e2.Source;//提供者名称
strEx = strEx + "/n" + "Number:" + e2.Number.ToString();//异常类型的数值
//异常文本(存储过程中的Orders Count is greater than 10-Notify the Business Manager)
strEx = strEx + "/n" + "Message:" + e2.Message;
strEx = strEx + "/n" + "Class:" + e2.Class.ToString();//级别
strEx = strEx + "/n" + "Procedure:" + e2.Procedure.ToString();//存储过程名称
strEx = strEx + "/n" + "Line Number:" + e2.LineNumber.ToString();//行号
strEx = strEx + "/n" + "Server:" + e2.Server.ToString();//计算机名
MessageBox.Show(strEx, "Database Exception");
}
catch (System.Exception e3)
{
string strEx;
strEx = "Source:" + e3.Source;
strEx = strEx + "/n" + "Error Message:" + e3.Message;
MessageBox.Show(strEx, "General Exception");
}
finally
{
cn.Close();
}
存储过程设法在Employees表中插入新雇员:
INSERT INTO Employees(EmployeeId,FirstName) VALUES(50,'Cinderella')
然而,由于Employees表中的EmployeeId列是Idenfity字段,所以,不能给EmployeeId显示赋值。
在数据库中
,
常用的一个流水编号通常会使用
identity
字段来进行设置
,
这种编号的好处是一定不会重复
,
而且一定是唯一的
,
这对
table
中的唯一值特性很重要
,
通常用来做客户编号
,
订单编号等功能。
3)错误集合
SqlException对象包含了Errors集合。Errors集合的每个项都是SqlError类型的对象。发生数据庫异常时,填充Errors集合。例如,让我们设法建立到不存在的数据庫连接,然后研究SqlException对象的Errors集合。
代码如下:
private void brnDBEx3_Click(object sender, EventArgs e)
{
//提供一个不存在的数据庫Northwnd
SqlConnection cn = new
SqlConnection(@"server=localhost;Integrated Security=SSPI;database=Northwnd");
SqlCommand cmd = cn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sp_DBException_2"; //设置存储过程名称
try
{
cn.Open();
cmd.ExecuteNonQuery();
}
catch (SqlException e2)
{
string strEx="";
for(int i=0;i {
strEx=strEx+"/n"+"Index#"+i+"/n"+"Exception:"+e2.Errors[i].ToString()+"/n"+"Number:"+
e2.Errors[i].Number.ToString()+"/n";
}
MessageBox.Show(strEx,"Database Exception");
}
catch (System.Exception e3)
{
string strEx;
strEx = "Source:" + e3.Source;
strEx = strEx + "/n" + "Error Message:" + e3.Message;
MessageBox.Show(strEx, "General Exception");
}
finally
{
cn.Close();
}
}
}
在设法打开连接时,会抛出SqlException类型的异常,
for(int i=0;i {
strEx=strEx+"/n"+"Index#"+i+"/n"+"Exception:"+e2.Errors[i].ToString()+"/n"+"Number:"+
e2.Errors[i].Number.ToString()+"/n";
}
MessageBox.Show(strEx,"Database Exception");
然后遍历Errors集合的各个项,使用Errors[I]语法得到每个Error对象。
这个例子表明,SqlException对象保存着Errors集合中每个SQL错误的详细信息。