异常捕获

                                    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错误的详细信息。

你可能感兴趣的:(数据庫知识园)