版权声明:Copyright:@@个人所有 https://blog.csdn.net/y20_20/article/details/90744676
目录
一、异常处理
二、程序中事务的一些用法介绍
一、异常的介绍和使用
1、异常的形式: 为了保证程序不会因为操作出现问题导致程序崩溃,需要添加异常。不处理异常会导致程序崩溃(CLR给出的 提示)
- try中写上可能会 发生异常错误的代码;程序本身会把发生异常错误的类型自动生成一个异常对象类
- catch中是捕获的异常,并处理异常,也可以写入日志(抛出和封装异常再抛出)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace exeception1
{
class Program
{
static void Main(string[] args)
{
try
{
int n = Convert.ToInt32(Console.ReadLine()); //产生异常的语句 (输入123cuowu)
Console.WriteLine("n转化为int类型后为:"+n);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);//输出产生的异常信息
}
Console.ReadKey();
}
}
}
2、异常处理的结构:
多路异常捕获:
try
{
会发生异常的代码都放在这里
}
catch(SqlException ex)//异常子类
{
SQLserver数据库异常信息;
//比如SQLserver数据库删除数据时,外键引用导致的错误 ,错误代码547
}
catch(Exception ex)//异常父类
{
SqlException异常没有捕获的异常,在这里一定能捕获
}
finally
{
不管有没有异常都会执行的代码都放在这里
}
3、对异常的处理方式:
- 立即处理: 产生异常后,给出提示或者处理其他逻辑使程序正常运行
- 抛出异常:对于复杂的程序,需要抛给上一层处理,也可以对异常进行封装后再抛出
二、程序中事务的一些使用介绍
在数据库端直接编写在存储过程内使用
1、为什么要使用事务: 执行多条增删改操作,保证要么都执行成功,要么都不执行
2、在程序端传输多条SQL语句的事务使用
两条一样的SQL语句:
sqlList.Add("insert into Students(studentName, gender, birthday, age, studentidno, classid) values('山运维','男','1998-07-21',23,'852074196385201234',2)");
sqlList.Add("insert into Students(studentName, gender, birthday, age, studentidno, classid) values('山运维','男','1998-07-21',23,'852074196385201234',2)");
运行结果:
其它异常信息:违反了 UNIQUE KEY 约束“uq_StudentIdNo”。不能在对象“dbo.Students”中插入重复键。重复键值为 (852074196385201234)。
语句已终止。
执行成功的事务:要么都成功,要么都失败
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//引入操作数据库所需要的命名空间
using System.Data;
using System.Data.SqlClient;
namespace text2
{
class Program
{
private static readonly string connString = @"Server=CHINA-20181227Q\server;DataBase=SMDB;User Id = sa; Password=123456";
static void Main(string[] args)
{
InsertByTransaction();
Console.ReadKey();
}
//通过传递SQL语句执行事务
public static void InsertByTransaction()
{
List<string> sqlList = new List<string>();
sqlList.Add("insert into Students(studentName, gender, birthday, age, studentidno, classid) values('山运维','男','1998-07-21',23,'852074196385201236',2)");
sqlList.Add("insert into Students(studentName, gender, birthday, age, studentidno, classid) values('张建坤','男','1998-07-21',23,'852074196385201235',2)");
try
{
Console.WriteLine(Update(sqlList));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
/// <summary>
/// 执行增删改的数据操作方法
/// </summary>
/// <param name="sql">SQL语句集合</param>
/// <returns>返回受影响的行数</returns>
public static int Update(List<string> sqlList)
{
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
int count = 0;
try
{
conn.Open();
cmd.Transaction = conn.BeginTransaction();//开启数据库事务
foreach (var sql in sqlList)
{
cmd.CommandText = sql;
count+= cmd.ExecuteNonQuery();
}
cmd.Transaction.Commit();//提交事务
return count;//返回受影响的行数
}
catch (SqlException ex)
{
if (cmd.Transaction!=null)
{
cmd.Transaction.Rollback();//回滚事务(一旦多条SQL语句有一句错误,其余都不执行,回到执行前的状态)
}
if (ex.Number == 547)
{
throw new Exception("被操作的数据有外键约束,请删除外键约束后再试!详细信息:" + ex.Message);
}
throw new Exception("其它异常信息:" + ex.Message);
}
catch (Exception ex)
{
throw new Exception("操作 异常,请联系管理员!详细信息见:" + ex.Message);
}
finally
{
conn.Close();
}
}
}
}
结果:2
3、多次调用同一个存储过程的事务
数据库端的存储过程:
USE [SMDB]
GO
/****** Object: StoredProcedure [dbo].[usp_InsertStudent] Script Date: 2019/6/2 星期日 22:45:42 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[usp_InsertStudent]
--存储过程参数
@studentName varchar(20),
@gender char(2),
@birthday smalldatetime,
@age int,
@studentidno numeric(18,0),
@classid int
as
insert into Students(studentName,gender,birthday,age,studentidno,classid)
values(@studentName,@gender,@birthday,@age,@studentidno,@classid)
应用程序端掉用存储过程:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//引入操作数据库所需要的命名空间
using System.Data;
using System.Data.SqlClient;
namespace text2
{
class Program
{
private static readonly string connString = @"Server=CHINA-20181227Q\server;DataBase=SMDB;User Id = sa; Password=123456";
static void Main(string[] args)
{
InsertByTransaction();
Console.ReadKey();
}
//通过传递SQL语句执行事务
public static void InsertByTransaction()
{
//要添加的数据(可以是表单获取的,也可以是窗体控件获取的)
//string studentName = "山运维";//参数不能为空,并且不能出现多参数和少参数的情况
//string gender = "男";
//DateTime birthday = Convert.ToDateTime("1998-07-21");
//int age = 18;
//string studentidno = "852074196385201234";
//int classid = 2;
SqlParameter[] param1 = new SqlParameter[]
{
new SqlParameter("@studentname","山运维"),
new SqlParameter("@gender","男"),
new SqlParameter("@birthday",Convert.ToDateTime("1998-07-21")),
new SqlParameter("@age",18),
new SqlParameter("@studentidno","852074196385201234"),
new SqlParameter("@classid",2)
};
SqlParameter[] param2 = new SqlParameter[]
{
new SqlParameter("@studentname","张建坤"),
new SqlParameter("@gender","男"),
new SqlParameter("@birthday",Convert.ToDateTime("1998-07-21")),
new SqlParameter("@age",18),
new SqlParameter("@studentidno","852074196385201235"),
new SqlParameter("@classid",2)
};
List<SqlParameter[]> paramList = new List<SqlParameter[]>();
paramList.Add(param1);
paramList.Add(param2);
try
{
Console.WriteLine(Update("usp_InsertStudent",paramList));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
/// <summary>
/// 反复调用同一个存储过程
/// </summary>
/// <param name="procedureName"></param>
/// <param name="paramList"></param>
/// <returns></returns>
public static int Update(string procedureName, List<SqlParameter[]> paramList)
{
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(procedureName,conn);
cmd.CommandType= CommandType.StoredProcedure;
int count = 0;
try
{
conn.Open();
cmd.Transaction = conn.BeginTransaction();//开启数据库事务
foreach (var param in paramList)
{
cmd.Parameters.Clear();//清空参数
cmd.Parameters.AddRange(param);
count+= cmd.ExecuteNonQuery();
}
cmd.Transaction.Commit();//提交事务
return count;//返回受影响的行数
}
catch (SqlException ex)
{
if (cmd.Transaction!=null)
{
cmd.Transaction.Rollback();//回滚事务(一旦多条SQL语句有一句错误,其余都不执行,回到执行前的状态)
}
if (ex.Number == 547)
{
throw new Exception("被操作的数据有外键约束,请删除外键约束后再试!详细信息:" + ex.Message);
}
throw new Exception("其它异常信息:" + ex.Message);
}
catch (Exception ex)
{
throw new Exception("操作 异常,请联系管理员!详细信息见:" + ex.Message);
}
finally
{
conn.Close();
}
}
}
}
执行成功返回结果:2
4、多次调用不同的存储过程的事务
数据库端的存储过程创建:
存储过程一:
create procedure [dbo].[usp_InsertStudent1]
--存储过程参数
@studentName varchar(20),
@gender char(2),
@birthday smalldatetime,
@age int,
@studentidno numeric(18,0),
@classid int
as
insert into Students(studentName,gender,birthday,age,studentidno,classid)
values(@studentName,@gender,@birthday,@age,@studentidno,@classid)
存储过程二:
create procedure [dbo].[usp_InsertStudent]
--存储过程参数
@studentName varchar(20),
@gender char(2),
@birthday smalldatetime,
@age int,
@studentidno numeric(18,0),
@classid int
as
insert into Students(studentName,gender,birthday,age,studentidno,classid)
values(@studentName,@gender,@birthday,@age,@studentidno,@classid)
VS代码测试:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//引入操作数据库所需要的命名空间
using System.Data;
using System.Data.SqlClient;
namespace text2
{
class Program
{
private static readonly string connString = @"Server=CHINA-20181227Q\server;DataBase=SMDB;User Id = sa; Password=123456";
static void Main(string[] args)
{
InsertByTransaction();
Console.ReadKey();
}
//通过传递SQL语句执行事务
public static void InsertByTransaction()
{
//要添加的数据(可以是表单获取的,也可以是窗体控件获取的)
//string studentName = "山运维";//参数不能为空,并且不能出现多参数和少参数的情况
//string gender = "男";
//DateTime birthday = Convert.ToDateTime("1998-07-21");
//int age = 18;
//string studentidno = "852074196385201234";
//int classid = 2;
SqlParameter[] param1 = new SqlParameter[]
{
new SqlParameter("@studentname","山运维"),
new SqlParameter("@gender","男"),
new SqlParameter("@birthday",Convert.ToDateTime("1998-07-21")),
new SqlParameter("@age",18),
new SqlParameter("@studentidno","852074196385201234"),
new SqlParameter("@classid",2)
};
SqlParameter[] param2 = new SqlParameter[]
{
new SqlParameter("@studentname","张建坤"),
new SqlParameter("@gender","男"),
new SqlParameter("@birthday",Convert.ToDateTime("1998-07-21")),
new SqlParameter("@age",18),
new SqlParameter("@studentidno","852074196385201235"),
new SqlParameter("@classid",2)
};
Dictionary<string, SqlParameter[]> paramAndprocedure = new Dictionary<string, SqlParameter[]>();
paramAndprocedure.Add("usp_InsertStudent1",param1);
paramAndprocedure.Add("usp_InsertStudent", param2);
try
{
Console.WriteLine(Update(paramAndprocedure));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static int Update(Dictionary<string ,SqlParameter[]> paramAndprocedure)
{
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandType= CommandType.StoredProcedure;
int count = 0;
try
{
conn.Open();
cmd.Transaction = conn.BeginTransaction();//开启数据库事务
foreach (var procedureName in paramAndprocedure.Keys)
{
cmd.CommandText = procedureName;
if (paramAndprocedure[procedureName].Length > 0)//判断是否有参数
{
cmd.Parameters.Clear();//清空参数
cmd.Parameters.AddRange(paramAndprocedure[procedureName]);
}
count+= cmd.ExecuteNonQuery();
}
cmd.Transaction.Commit();//提交事务
return count;//返回受影响的行数
}
catch (SqlException ex)
{
if (cmd.Transaction!=null)
{
cmd.Transaction.Rollback();//回滚事务(一旦多条SQL语句有一句错误,其余都不执行,回到执行前的状态)
}
if (ex.Number == 547)
{
throw new Exception("被操作的数据有外键约束,请删除外键约束后再试!详细信息:" + ex.Message);
}
throw new Exception("其它异常信息:" + ex.Message);
}
catch (Exception ex)
{
throw new Exception("操作 异常,请联系管理员!详细信息见:" + ex.Message);
}
finally
{
conn.Close();
}
}
}
}
执行成功测试结果:返回2