标签:事务 拆箱 windows eal 建立 成功 OLE HERE new
ADO.net
概念
ADO.net是.net框架中用来操作数据库的一种机制。支持多种数据库。它允许用户用相同或相似的代码,来操作多种不同类型的数据库。比如: sql server、access、mysql、sqlite、oracle、excel
ADO.net操作流程
1、连接字符串
它就是一段,包含了连接数据库所需要的信息的字符串。我们需要在连接数据库的同时将这段字符串传递给数据库,以验证登记数据库服务器的信息是否正确。示例:
string strConn = “server = . ;database = test ; uid = sa ; pwd = sa ”
其中:
server 数据库服务器的IP地址或计算机名。(代表本机有三种写法,.一圆点、127.0.0.1、localhost)。database 选择要进行操作的数据库。uid 登陆数据库服务器的用户名。password或pwd 登陆数据库服务器的用户密码
2、数据连接对象
一切皆对象,数据连接它一个对象: System.Data.SqlClient.SqlConnection
定义数据连接对象示例1:
SqlConnection conn = new SqlConnection(strConn);
定义数据连接对象示例2:
SqlConnection conn = new SqlConnection(); conn.ConnectionString = strConn;
先定义数据连接对象,再为其ConnectionString 属性赋值,因此这个属性就是连接对象中的连接字符串信息。
3、打开数据连接
数据连接对象必须进行open()打开操作,本地应用程序与远程数据库,才会真正的建立起数据连接来。示例:
conn.Open();
如果连接信息有误,则会抛出异常。
ADO.net中查询操作数据库的两种方式
SqlCommand方式
也叫做长连接方式,就是指在操作数据库的过程中,你的应用程序与数据库服务器始终是保持连接的。
SqlAdapter方式
这是一种瞬间连接,就是指它只是在操作数据库的瞬间进行连接,然后就立即断开。比如:查询数据时,它会一次性读出数据,然后放在应用程序所在计算机的内存中。
4、SqlCommand长连接
SqlCommand也是以类的方式存在的,command是命令的意义,该类的作用就是执行sql语句,示例:
SqlCommand sCmd = new SqlCommand(strSql,conn);
SqlCommand类的构造函数需要两个参数,第一个是要被执行的sql语句,第二个是(已经打开的)连接对象。
或
string strSql = "select * from student"; SqlCommand sCmd = new SqlCommand(); sCmd.CommandText = strSql; //要执行的SQL语句 sCmd.Connection = conn; //数据库连接对象
5.SqlDataReader读取查询
这个对象用来获取sqlCommand执行sql查询语句之后所返回的结果集,但它并不是结果集本身,而只是一个读取器。
示例:
SqlDataReader dRead = sCmd.ExecuteReader(); 通过sCmd对象的ExecuteReader()方法,来获取一个用来执行查询语句的阅读器 if (dRead.HasRows) //判断dRead中是否包含数据 { while (dRead.Read()) { //Read方法用来读取下一条数据,如果没有下一条数据的话,返回false //每次执行Read方法,返回一行数据,一行数据中包含若干列,如果要读取这一行中的某列数据就用要格式: //dRead["字段名"]或dRead[字段序号] string sId = dRead[0].ToString(); string sName = dRead["name"].ToString(); int sAge = (int)dRead["age"]; Console.WriteLine("{0}号的学生{1}的年龄是{2}",sId,sName,sAge); } }
6、执行增删改操作
执行增删改的过程中不需要SqlDataReader对象,只需要执行SqlCommand对象的ExecuteNonQuery()方法即可。
string strConn = "server=.;database=test;uid=sa;pwd=sa"; SqlConnection conn = new SqlConnection(strConn); conn.Open(); string strSql = "insert into student(name,age,sex,[address],phone) values(‘小王‘,19,1,‘上海虹口‘,‘1010110‘) "; SqlCommand sCmd = new SqlCommand(strSql,conn); int result = sCmd.ExecuteNonQuery(); Console.WriteLine(result+"行受影响"); conn.Close();
7、DataSet数据集
它是内存之中的数据缓存,它是一种集合,当我们在用瞬间连接的方式来查询数据的时候,它就是在内存中的临时数据表。它就是好像是一个内存中的数据库。定义语法:
DataSet ds = new DataSet();
它的命名空间是System.Data;
8、SqlDataAdapter数据适配(填充)器
它的作用就是将数据库读取出来的数据填充到DataSet中,示例:
string strSql = "select * from student "; DataSet ds = new DataSet(); SqlDataAdapter da = new SqlDataAdapter(strSql,conn); da.Fill(ds); //用fill()方法读取数据库并将内容填充入ds数据集 foreach (DataRow dr in ds.Tables[0].Rows) {//ds.Tables[0].Rows代表ds中的第一张表中的所有行的集合 //通过遍历来得到DataRow数据行对象,一行数据中包含了若干列,如果要读取某列数据用类似格式:dr["字段名"] 或 dr[字段序号] string sId = dr[0].ToString(); string sName = dr["name"].ToString(); int sAge = (int)dr["age"]; Console.WriteLine("{0}号的学生{1}的年龄是{2}岁",sId,sName,sAge); }
9、释放服务器资源
需要被释放的资源有:数据集、连接对象、DataReader对象,其数据集用dispose()方法释放,连接对象和DataReader是用close()来释放。
小练习:
建立数据连接,然后用sqlCommad对象来执行”Create Table”指令在数据库中创建一个数据表(学生编号_主键自增、学生姓名、性别、班级、电话),然后用qlCommad对象来执行Insert语句插入至少五条学生数据。利用SqlDataReader对象在控制台上循环显示出所有学生数据。用DataSet方式来读取出所有男生的数据。
ADO.net中的类
SqlConnection类。数据连接对象
常用的类成员
ConnectionString 数据库的连接字符串
Open() 打开数据连接
Close() 关闭数据连接
SqlCommand类
位于System.Data.SqlClient,它用于向数据库发送并执行Sql语句。
SqlCommand类的常见属性
属性 |
说明 |
CommandText |
获取或设置要对数据源执行的T-SQL语句或存储过程 |
Connection |
执行T-SQL语句时所使用的数据连接 |
CommandType |
获取或设置所执行的命令的类型 |
CommandTimeout |
获取或设置在终止执行命令的尝试并生成错误之前的等待时间。 |
Parameters |
获取所执行的命令的参数的集合 |
SqlCommand类的常见方法
方法 |
说明 |
ExecuteNonQuery |
执行非查询命令并返回受影响的行数 |
ExecuteReader |
执行查询并生成一个SqlDataReader |
ExecuteScalar |
执行查询,并返回查询结果的第一行的第一列。 |
ExecuteXmlReader |
执行查询并生成一个SqlXmlReader |
SqlDataReader类
位于System.Data.SqlClient,获取Sqlcommand执行select语句之后返回的可以得到结果的阅读器(只是阅读,并不是查询结果的集合)。
sqlDataReader常用属性
属性名 |
说明 |
Connection |
获取与SqlDataReader关联的SqlConnection |
FiledCount |
获取当前查询中包含多少列 |
HasRows |
获取一个值,该值表示当前查询中结果是否包含至少一条数据。 |
Item |
以索引的方式获取指定数据列的值 |
sqlDataReader常用方法
方法名 |
说明 |
Close() |
关闭sqlDataReader对象 |
Get*****(数据类型) |
获取指定列的指定数据类型形式的值。 |
NextResult |
当读取T-Sql语句的结果时,使用数据读取器前进到下一结果 |
Read |
使用读取数据的指针前进到下一条,并且返回该行数据。 |
DataSet及其子类
DataSet的子类
DataSet数据庥完全可以看作是一个内存中的数据库,一个DataSet可以包含若干个DataTable数据表,每个数据表中又包含了DataRow数据行与DataColumn数据列。
表与表之间还包含表间关系DataRelation
常用属性
Tables 获取包含在DataSet中的表的集合。
DataColumn数据列类
常用属性
属性 |
描述 |
ColumnName |
获取或设置字段名 |
DataType |
获取或设置指定字段中的数据的类型 |
MaxLength |
获取或设置文件列的最大长度 |
DataTable数据表类
常用属性
属性 |
描述 |
Columns |
获取属于该表的列的集合 |
Rows |
获取属于该表的行的集合 |
TableName |
获取或设置DataTable的名称 |
DataRow数据行类
常用类成员
成员 |
描述 |
Item |
索引,获取或设置存储在指定列中的数据 |
IsNull() |
获取一个值,该值表示指定的列中是否包含null值 |
SetNull() |
将指定的字段值设置为null |
SqlDataAdapter类
常用方法
Fill 将数据填充到数据集中
Update 将DataSet中修改的数据更新到数据库
常用属性
SelectCommand 获取或设置用于执行查询的命令对象
InsertCommand 获取或设置用于执行插入的命令对象
UpdateCommand 获取或设置用于执行更新的命令对象
Deleteommand 获取或设置用于执行删除的命令对象
ADO.net技巧
取数据时的拆箱操作
示例1,SqlDataReader中的拆箱方法
string strSql = "select * from t_student"; SqlCommand sCmd = new SqlCommand(strSql,conn); SqlDataReader dr = sCmd.ExecuteReader(); if (!dr.HasRows) return; while(dr.Read()){ int sid = dr.GetInt32(0); string sName = dr.GetString(1); DateTime BirthDay = dr.GetDateTime(3); Console.WriteLine(sid+"----"+sName+"----"+BirthDay); }
SqlDataReader类包含多个以Get…开头的方法,它们的作用是在取出指定字段数据的同时,将其转换为指定的数据类型。
示例2
string strSql = "select * from t_student"; SqlDataAdapter sAdp = new SqlDataAdapter(strSql,conn); DataSet ds = new DataSet(); sAdp.Fill(ds); foreach (DataRow dr in ds.Tables[0].Rows) { string sName = Convert.ToString(dr["RealName"]); int sid = Convert.ToInt32(dr["StudentID"]); DateTime birth = Convert.ToDateTime(dr["BirthDay"]); Console.WriteLine(sid+"-----"+sName+"------"+birth); }
Parameters参数的使用
直接拼接sql语句
int id = 1; string sql = “select * from where id=”+id; string name=”刘老师”; string sql = “insert into user vlues(“+name+”)”;
但是,这样做不但容易出错,也不安全
name = “ ‘tom’;insert into admin vluse(‘admin’,’123456 ” string sql = “insert into user vlues(“+name+”)”;
这是很基础的黑客攻击方式,SQL注入。
sqlParameters类
它起了类似占位符的作用,同时也可以防止sql注入攻击。
sqlParameters示例
string strSql = "select * from t_student where Gender=@sex and ClassID=@ClassID"; //SqlParameter的占位符:@名称 SqlCommand scmd = new SqlCommand(strSql,conn); SqlParameter para1 = new SqlParameter("@sex",SqlDbType.Bit,1); /*三个参数分别代表 *1、占位符名称 *2、要加入的字段的数据类 *3、要加入的字段的长度(可选) *4、如果占位符代表的是字符类型的值,则不需要加单引号。比如:‘@sex‘这样是错的 */ para1.Value = 1; //通过value属性为参数赋值 SqlParameter para2 = new SqlParameter("@ClassID",SqlDbType.Int); para2.Value = 2; scmd.Parameters.Add(para1); scmd.Parameters.Add(para2); SqlDataReader dr = scmd.ExecuteReader(); while (dr.Read()) { string sName = Convert.ToString(dr["RealName"]); int sid = Convert.ToInt32(dr["StudentID"]); DateTime birth = Convert.ToDateTime(dr["BirthDay"]); Console.WriteLine(sid+"-----"+sName+"------"+birth); } sqlDataAdapter示例 string strConn = "server=.;database=Test;uid=sa;pwd=sa"; SqlConnection conn = new SqlConnection(strConn); conn.Open(); string strSql = "select * from t_student where Gender=@sex and ClassID=@ClassID"; //定义SqlParameter数组,存放所需要的参数对象 SqlParameter[] prams ={ new SqlParameter("@sex",SqlDbType.Bit), new SqlParameter("@ClassID",SqlDbType.Int), }; prams[0].Value = 1; //对数组中的每个参数对象赋值 prams[1].Value = 2; SqlDataAdapter adp = new SqlDataAdapter(strSql,conn); adp.SelectCommand.Parameters.AddRange(prams); //SelectCommand代表了适配器的select查询指令对象,其本质是一个SqlCommand对象 //AddRange()方法用于将数据中的参数,应用到sql语句的每个占位符。 DataSet ds = new DataSet(); adp.Fill(ds); foreach (DataRow dr in ds.Tables[0].Rows) { string sName = Convert.ToString(dr["RealName"]); int sid = Convert.ToInt32(dr["StudentID"]); DateTime birth = Convert.ToDateTime(dr["BirthDay"]); Console.WriteLine(sid+"-----"+sName+"------"+birth); }
DataSet增删改与更新
我们都已经知道DataSet数据集是内存中的一个”临时数据库”,我们可以对这个”临时内存数据库”进行增删改操作,然后将修改的内容同步更新到远程数据库中。
添加数据
DataSet ds = new DataSet(); string strSql = "select * from student"; SqlDataAdapter adp = new SqlDataAdapter(strSql,conn); //为填充入ds数据集的数据表起一个表名 adp.Fill(ds,"student"); //生成要被添加的数据行的对象,通过"数据表.NewRow()"方法,来创建一个专属于这张表的数据行对象 DataRow dr = ds.Tables["student"].NewRow(); dr["name"] = "小钱"; dr["age"] = 20; dr["sex"] = true; dr["address"] = "某市某区某街某小区"; dr["phone"] = "13983838383"; //将数据行对象添加入数据表的行集合中 ds.Tables["student"].Rows.Add(dr); foreach (DataRow drItem in ds.Tables["student"].Rows) Console.WriteLine(drItem["name"].ToString());
更新数据
将DataSet中的数据修改的内容更新同步应用到数据库中,需要执行SqlDataAdapter对象的Update()方法。
string strSql = "select * from student"; SqlDataAdapter adp = new SqlDataAdapter(strSql,conn); //为填充入ds数据集的数据表起一个表名 adp.Fill(ds,"student"); //生成要被添加的数据行的对象,通过"数据表.NewRow()"方法,来创建一个专属于这张表的数据行对象 DataRow dr = ds.Tables["student"].NewRow(); dr["name"] = "小钱"; dr["age"] = 20; dr["sex"] = true; dr["address"] = "某市某区某街某小区"; dr["phone"] = "13983838383"; //将数据行对象添加入数据表的行集合中 ds.Tables["student"].Rows.Add(dr); //自动生成insert语句,也就是将我们刚才对dataSet执行的操作步骤转换为相应的SQL语句 //通过SqlCommandBuilder来得到Sql语句,它会在dataSet中找到我们的操作步骤用以转换,我们可以用InsertCommand的CommandText属性来看到这个insert语句 SqlCommandBuilder sCmd = new SqlCommandBuilder(adp); adp.InsertCommand = sCmd.GetInsertCommand(); Console.WriteLine(adp.InsertCommand.CommandText); adp.Update(ds,"student"); //更新数据库 foreach (DataRow drItem in ds.Tables["student"].Rows) Console.WriteLine(drItem["name"].ToString());
更新不是执行一下update()方法它就能很智能的自动完成了,因为sql server它只认t-sql语句,所以必须要生成相应的sql语句才行。
update语法
SqlDataAdapter对象.Update(数据集) //当数据集中只有一张表时。
或
SqlDataAdapter对象.Update(数据集,表名) //当数据集中有多张表时。
修改数据
string strSql = "select * from student"; SqlDataAdapter adp = new SqlDataAdapter(strSql,conn); //为填充入ds数据集的数据表起一个表名 adp.Fill(ds,"student"); ds.Tables[0].Rows[0]["name"] = "江小白"; ds.Tables[0].Rows[0]["age"] = 22; //生成sql语句 SqlCommandBuilder sBulid = new SqlCommandBuilder(adp); adp.UpdateCommand = sBulid.GetUpdateCommand(); Console.WriteLine(adp.UpdateCommand.CommandText); //更新 adp.Update(ds,"student");
删除数据
需要用到方法:DataRow对象 . Delete();
比如:
string strSql = "select * from student"; SqlDataAdapter adp = new SqlDataAdapter(strSql,conn); //为填充入ds数据集的数据表起一个表名 adp.Fill(ds,"student"); //删除指定的数据行 ds.Tables["student"].Rows[0].Delete(); ds.Tables["student"].Rows[4].Delete(); //生成sql语句 SqlCommandBuilder sBuild = new SqlCommandBuilder(adp); adp.DeleteCommand = sBuild.GetDeleteCommand(); Console.WriteLine(adp.DeleteCommand.CommandText); adp.Update(ds,"student"); //更新
在数据集中查找符合条件的数据行
当然我们也可以用循环来一个个的遍历查找数据,但这样性能太差。因此我们可以用DataTable的Select方法,该方法包含一个字符型参数,该参数就是select语句中的where子句部分。
string strConn = "server=.;database=test;uid=sa;pwd=sa"; SqlConnection conn = new SqlConnection(strConn); conn.Open(); DataSet ds = new DataSet(); string strSql = "select * from student"; SqlDataAdapter adp = new SqlDataAdapter(strSql,conn); //为填充入ds数据集的数据表起一个表名 adp.Fill(ds,"student"); DataRow[] drArr = ds.Tables["student"].Select(" age>19 and age<22"); foreach (DataRow dr in drArr) Console.WriteLine(dr["name"].ToString()+"-----"+dr["age"].ToString());
DataView是DataSet的视图功能
其功能类似于数据库的视图,示例:
string strSql = "select * from student"; SqlDataAdapter adp = new SqlDataAdapter(strSql,conn); //为填充入ds数据集的数据表起一个表名 adp.Fill(ds,"student"); //实例化视图对象 DataView dv = new DataView(); dv = ds.Tables[0].DefaultView; //设置该视图的源数据来自于哪张表 dv.RowFilter = " sex = 0 and age<=21 "; //视图中数据的过滤条件,相当于select的where子句 DataTable dt = dv.ToTable(); //将视图的内容转存到数据表中 foreach (DataRow dr in dt.Rows) Console.WriteLine(dr["name"].ToString()+"----"+dr["age"].ToString());
判断DataSet是否有改动
用数据集实例的HasChanges属性,来判断该数据集与数据库中的数据是否已经不一致了,返回bool值。
ds.Tables[0].Rows[0]["name"] = "小小强"; Console.WriteLine(ds.HasChanges());
数据集的表间关系DataRelation
就是表与表的外键关系,请自行百度。
自定义数据集及其内容(非数据库读取)
当我们需要在内存中虚拟一个数据库的时候,Dataset是比集合功能更强大的工具。
DataSet ds = new DataSet(); //ds.Tables.Add(dt); //将数据表添加入数据集 ds.Tables.Add("student"); //在数据集中添加一张空的student数据表 DataTable dt = ds.Tables["student"]; //新建数据表对象 DataColumn dc1 = new DataColumn("id"); //创建数据字段对象id dc1.DataType=typeof(int); //指定字段id的数据类型 DataColumn dc2 = new DataColumn("name"); dc2.DataType = typeof(System.String); dt.Columns.Add(dc1); //将字段对象添加到这张表的字段集合中 dt.Columns.Add(dc2); dt.PrimaryKey = new DataColumn[1] { dc1 }; //设置数据表的主键 for (int i = 1; i <= 10; i++) { DataRow dr = dt.NewRow(); //创建新的数据行 dr["name"] = "学生00" + i; //向新行中添加数据 dr["id"] = i; dt.Rows.Add(dr); //将新行添加入行集合 } foreach (DataRow dr in ds.Tables[0].Rows) { Console.WriteLine(dr["id"].ToString()+"-----"+dr["name"].ToString()); }
小练习
建立数据库与学生数据表(学生编号_主键自增、学生姓名、性别、班级、电话),然后用DataSet方式插入至少五条学生数据。然后实现通过控制台来查询、删除、修改、添加学生数据。
用ADO.net执行存储过程
只返回一个记录集的存储过程
就是说返回一个select语句的查询结果。
string strConn = "server=.;database=test;uid=sa;pwd=sa"; SqlConnection conn = new SqlConnection(strConn); conn.Open(); //执行存储过程也是通过sqlCommand对象 SqlCommand scmd = new SqlCommand(); scmd.Connection = conn; scmd.CommandText = "pp1"; //这里要执行的语句就是存储过程的名字 //指定当前要执行的语句为类型是存储过程 scmd.CommandType = System.Data.CommandType.StoredProcedure; SqlDataAdapter dp = new SqlDataAdapter(scmd); DataSet ds = new DataSet(); dp.Fill(ds,"pp1_result"); foreach (DataRow dr in ds.Tables[0].Rows) Console.WriteLine(dr["name"]+"-----"+dr["age"]+"-----"+dr["address"]);
存储过程的内容:
create proc pp1 as select * from student go
没有输入输出参数的存储过程
存储过程
create proc pp2 as insert into student(name,age,sex) values(‘小宝‘,37,1) go
C#代码
SqlCommand scmd = new SqlCommand(); scmd.Connection = conn; scmd.CommandText = "pp2"; scmd.CommandType = CommandType.StoredProcedure; int result = scmd.ExecuteNonQuery(); Console.WriteLine("{0}行受到影响",result);
有返回值的存储过程
存储过程:
create proc pp3 as insert into student(name,age,sex) values(‘小蓉‘,37,1) return @@rowcount --受影响的行数 go
C#代码:
SqlCommand scmd = new SqlCommand("pp3",conn); scmd.CommandType = CommandType.StoredProcedure; //创建参数 IDataParameter[] parmeters = { new SqlParameter("rval",SqlDbType.Int,4) //参数名:rval 参数类型int 参数长度 4位 }; //将参数类型设置为返回值 parmeters[0].Direction = ParameterDirection.ReturnValue; //添加参数 scmd.Parameters.Add(parmeters[0]); //执行存储过程 int result = scmd.ExecuteNonQuery(); string returnValue = parmeters[0].Value.ToString(); //显示受影响的行数和返回值 Console.WriteLine("受影响的行数"+result + "返回值"+returnValue);
有输入参数和输出参数的存储过程
存储过程:
create proc pp4 @id int output, @sName nvarchar(50) as Insert into student(name,age,sex) values(@sName,19,1) set @id=@@IDENTITY go
C#代码:
SqlCommand scmd = new SqlCommand("pp4",conn); scmd.CommandType = CommandType.StoredProcedure; //创建参数 IDataParameter[] parmeters = { new SqlParameter("@id",SqlDbType.Int, 4), new SqlParameter("@sName",SqlDbType.NVarChar,50) }; //将参数类型设置为输出参数 parmeters[0].Direction = ParameterDirection.Output; parmeters[1].Value = "宝宝"; //新同学的姓名 //添加到参数集合中 scmd.Parameters.AddRange(parmeters); //执行存储过程,并得到受影响的行数 int result =scmd.ExecuteNonQuery(); //获取输出参数 string returnValue = parmeters[0].Value.ToString(); //显示结果 Console.WriteLine("受影响的行数"+result+"输出参数"+returnValue);
同时具有返回值、输入参数、输出参数
存储过程
create proc pp5 @id int output, @sName nvarchar(50) as Insert into student(name,age,sex) values(@sName,19,1) set @id=@@IDENTITY return @@rowcount go
C#代码
SqlCommand scmd = new SqlCommand("pp5",conn); scmd.CommandType = CommandType.StoredProcedure; //创建参数数组 SqlParameter[] parmeters ={ new SqlParameter("@id",SqlDbType.Int,4), new SqlParameter("@sName",SqlDbType.NVarChar,50), new SqlParameter("rval",SqlDbType.Int,4) //rval就代表返回值的参数名 }; //设置参数类型为输出参数 parmeters[0].Direction = ParameterDirection.Output; parmeters[1].Value = "小新"; parmeters[2].Direction = ParameterDirection.ReturnValue; //将数组添加入参数集合 scmd.Parameters.AddRange(parmeters); //执行存储过程 int result = scmd.ExecuteNonQuery(); //获取输出参数 string outVal = parmeters[0].Value.ToString(); //获取返回值 string returnValue = parmeters[2].Value.ToString(); //显示受影响的行数和返回值 Console.WriteLine("受影响的行数" + result + "返回值" + returnValue + "输出值" + outVal);
同时有返回参数、输入输出参数和记录集的存储过程
存储过程
create proc pp6 @id int output, @sName nvarchar(50) as Insert into student(name,age,sex) values(@sName,19,1) set @id=@@IDENTITY select * from student return @@rowcount go
C#代码
SqlCommand scmd = new SqlCommand("pp6",conn); scmd.CommandType = CommandType.StoredProcedure; SqlParameter[] parmeters ={ new SqlParameter("@id",SqlDbType.Int,4), new SqlParameter("@sName",SqlDbType.NVarChar,50), new SqlParameter("rval",SqlDbType.Int,4) }; parmeters[0].Direction = ParameterDirection.Output; parmeters[1].Value = "小丸子"; parmeters[2].Direction = ParameterDirection.ReturnValue; scmd.Parameters.AddRange(parmeters); //创建适配器以执行存储过程,并向数据集填充查询结果。 SqlDataAdapter dp = new SqlDataAdapter(scmd); DataSet ds = new DataSet(); dp.Fill(ds); //将存储过程的结果集填充入ds //这里已经不需要再运行前几个示例中的ExecuteNonQuery()方法了,因为Fill()方法已经执行了多步操作,比如:传入参数、得到输出参数和返回值,同时将记录集填充入ds string outputValue = parmeters[0].Value.ToString(); string returnValue = parmeters[2].Value.ToString(); Console.WriteLine("返回值" + returnValue + "输出值" + outputValue); DataTable dt = ds.Tables[0]; foreach (DataRow dr in dt.Rows) Console.WriteLine(dr["name"]+"------"+dr["age"]);
返回多个记录集的存储过程
存储过程
create proc pp7 as select * from student select * from teacher go
C#
SqlCommand scmd = new SqlCommand("pp7",conn); scmd.CommandType = CommandType.StoredProcedure; //创建适配器 SqlDataAdapter dp = new SqlDataAdapter(scmd); DataSet ds = new DataSet(); //执行存储过程,并将返回的记录集填充到ds中 dp.Fill(ds); //如果有两个查询结果集的话,DataSet会自动帮你建两张DataTable数据表分别存放两个结果集 DataTable dt0 = ds.Tables[0]; DataTable dt1 = ds.Tables[1]; Console.WriteLine("结果集1的内容如下:"); foreach (DataRow dr in dt0.Rows) Console.WriteLine(dr["name"] + "------" + dr["age"]); Console.WriteLine("结果集2的内容如下:"); foreach (DataRow dr in dt1.Rows) Console.WriteLine(dr["name"] + "------" + dr["age"]);
小练习:
用存储过程,实现分页功能,传入表名、每页大小、当前页码、是否降序。然后用C#来调用这个存储过程,并显示分页后的结果。
ADO.net操作Access数据库
Access软件
Access是office办公套件之一,它是一种轻量级的数据库,这种数据库文件可以任一复制存放,不需要配置或启动任何服务。(只要安装了access的驱动就可以使用。只要安装了office就自带access的驱动。)
连接access数据库
总体的过程与连接sql server数据库类似,但是要注意的是他们的连接字符串不一样(2003版的mdb文件与2007版及之后版本的accdb文件的连接字符串也不一样)。
.accdb数据库的连接字符串
Provider 代表所支持的驱动程序及其版本
Data Source 数据库文件的路径
Persist Security Info 是否使用安全信息
示例
string strConn = "Provider=MicroSoft.ACE.OLEDB.12.0;"; strConn += @"Data Source=D:\db\test.accdb;"; strConn += "Persist Security Info=False"; OleDbConnection conn = new OleDbConnection(strConn); conn.Open(); string strSql = "select * from student"; OleDbCommand cmd = new OleDbCommand(strSql,conn); OleDbDataReader dRead = cmd.ExecuteReader(); Console.WriteLine("共有{0}个字段",dRead.FieldCount); if (!dRead.HasRows) return; while (dRead.Read()) { Console.WriteLine("id :" + dRead.GetInt32(0)); Console.WriteLine("\t 姓名 :" + dRead.GetString(1)); Console.WriteLine("\t 年龄 :" + dRead.GetInt32(2)); } dRead.Close(); conn.Close(); 在Access中实现增删改 string strConn = "Provider=MicroSoft.ACE.OLEDB.12.0;"; strConn += @"Data Source=D:\db\test.accdb;"; strConn += "Persist Security Info=False"; OleDbConnection conn = new OleDbConnection(strConn); conn.Open(); //string strSql = "insert into student(sName,sAge,sAddress) values(‘小白‘,7,‘某山某沟某乡某大队‘)"; //string strSql = "update student set sName=‘小黑‘ where id=4"; string strSql = "delete from student where id=4"; OleDbCommand cmd = new OleDbCommand(strSql,conn); int result = cmd.ExecuteNonQuery(); Console.WriteLine("受影响的行数:"+result); conn.Close();
常见错误
1、“文件正在使用”:有可能你正在通过office access软件打开这个数据库文件,关闭该软件即可。
2、”权限或IO错误”:就需要去查看数据库文件及所在目录,是否为只读、系统文件,是否对该文件有足够的操作权限(比如你登录的windows帐号没有操作该文件的权限)
ADO.net操作MySql数据库
每种数据库连接的关键,还是在于其连接字符串。因为连接字符串中包含了数据库所需要的驱动、类型、帐号密码等信息。.net framework并不是天生支持mySql的。因此,我们需要从外部引用支持mysql数据库的类库。
引用Mysql.Data外部类库
已经封装好的外部类文件扩展是.dll,通常称为动态链接库。
到mysql官网去下载对.net支持的类文件
在下载文件中找到相应的.net版本的mySql.Data.dll文件
将文件放在应用程序的..\bin\Debug\目录下。(右击项目名à在windows资源管理器中打开文件夹)
在项目à“引用”节点à右击弹出菜单à添加引用à浏览Browse à选择刚复制的dll文件并确定。
如果看到引用的类的列表中多了一项:MySql.Data,就说明引用成功了。
这种方式也适用于引用其他第三方类库。
MySql的连接与查询
//mysql连接字符串 string strConn = "Host=localhost;Database=school;User Id=root;password=root;CharSet=utf8"; MySqlConnection conn = new MySqlConnection(strConn); conn.Open(); string strsql ="select * from student"; MySqlCommand sCmd = new MySqlCommand(strsql,conn); //using在此处的作用是规定sRead对象的作用域,超出这个范围之后它会自动被清除 using (MySqlDataReader sRead = sCmd.ExecuteReader()) { if (!sRead.HasRows) return; while (sRead.Read()) { Console.WriteLine("id:" + sRead.GetInt32(0)); Console.Write("---姓名:" + sRead.GetString(1)); Console.Write("---年龄:" + sRead.GetInt32(2)); } } conn.Close(); MySql中的添加操作 //mysql连接字符串 string strConn = "Host=localhost;Database=school;User Id=root;password=root;CharSet=utf8"; MySqlConnection conn = new MySqlConnection(strConn); conn.Open(); string strsql ="insert into student(sName,sAge,sAddress) values(‘阿土伯‘,67,‘台南‘)"; MySqlCommand sCmd = new MySqlCommand(strsql,conn); int result = sCmd.ExecuteNonQuery(); Console.WriteLine("受影响的行数" + result); conn.Close();
小练习
创建一个学生管理系统,首先显示一个菜单:1、遍历所有学生。2、根据ID查询某个学生。3、根据ID删除某个学生。4、根据ID修改某个学生。5、添加一个学生。数据要求通过Console.ReadLine()来输入,要求用ado.net+Mysql实现。
ado.net中的事务
string strConn = @"server=.\sqlexpress;Database=test;uid=sa;pwd=sa"; SqlConnection conn = new SqlConnection(strConn); conn.Open(); SqlCommand cmd = new SqlCommand(); cmd.Connection = conn; //声明一个事务对象 SqlTransaction myTrans; //开始事务,也就是开始记录sql操作。 myTrans = conn.BeginTransaction(); //返回一个事务对象 cmd.Transaction = myTrans; //将事务对象添加到sqlCommand中,也就是让指定对象拥有了事务功能。 //开始执行sql操作 try { cmd.CommandText = "Delete From student where id=8"; cmd.ExecuteNonQuery(); Console.WriteLine("成功删除一条数据"); cmd.CommandText = "insert into student (name,age,sex,address) values(‘小明‘,28,1,‘usa‘)"; cmd.ExecuteNonQuery(); cmd.CommandText = "insert into student (name,age,sex,addrefdsass) values(‘大明‘,38,1,‘hongkong‘)"; cmd.ExecuteNonQuery(); Console.WriteLine("插入两条数据"); myTrans.Commit(); //提交在刚才的事务过程中,所做的所有sql操作 } catch (Exception e) { //回滚事务 myTrans.Rollback(); Console.WriteLine("由于错误而导致所有操作取消"); }
标签:事务 拆箱 windows eal 建立 成功 OLE HERE new
原文地址:https://www.cnblogs.com/yigegaozhongsheng/p/9600123.html