SQL Server数据库读取数据的DateReader类及其相关类
之前学了几天的SQL Server,现在用C#代码连接数据库了。
需要使用C#代码连接数据库,读取数据。
涉及的类有:
- ConfigurationManage
- SqlConnection
- SqlCommand
- SqlDataReader
类名 | 功能 | 备注 |
ConfigurationManage | 用于读取配置文件中的数据库相关信息 | 没想到备注 |
SqlConnection | 用于连接对应数据库 | 使用前要Open,使用完毕后尽量Close |
SqlCommand | 用于存储要执行的sql语句,并执行sql语句,获得SQLDataReader实例或者一个int值 (该值是受影响的行数) | 每次执行前要对CommandText赋值, 也就是要执行的sql语句 |
SqlDataReader | 一行一行的去读取数据表的元组 | 读取元组时,只能从第一个元组开始读,一次读一个元组,不能回头 |
建库建表语句:
create database student; use student; create table student( sname nvarchar(20) not null, sno int not null, sage smallint not null, ssex char(2) not null ); alter table student add constraint PK_sno primary key (sno), constraint CK_sage check(sage between 8 and 40), constraint CK_ssex check(ssex = '男' or ssex = '女') insert into student values('张三',100, 23, '男'); insert into student values('李四',101, 24, '男'); insert into student values('王五',102, 25, '男'); insert into student values('赵六',103, 26, '男'); select * from student;
app.config配置文件中的写法:(记得要在reference中增加引用添加命名空间,System.Configuration)
关键字之间的空格也不能多,比如:data source之间只有一个空格。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> </startup> <connectionStrings> <add name="constr" connectionString="Data Source=ANAN\SQLEXPRESS;Initial Catalog=student;integrated Security=True;" providerName="System.Data.SqlClient" /> <!--<add name="TestConnectionString"这个是在C#代码里面获取数据库信息的key, 下面这些是数据库的一些信息: connectionString="Data Source=你的数据库实例名; Initial Catalog=数据库名字;(这里不是表名,记住) User ID=sa; Password=你自己的密码" providerName="System.Data.SqlClient" 也可以不使用密码账号登录,使用Windows用户登录也可以/>--> <!-- integrated Security=True; 这里是使用Windows验证的方式去连接到数据库服务器。 这样方式的好处是不需要在连接字符串中编写用户名和密码, 从一定程度上说提高了安全性。 --> <!-- providerName="System.Data.SqlClient" 说明使用的是MSSQLServer数据库 providerName="System.Data.SqlLite" 说明使用的是SQLLite数据库 providerName="System.Data.OracleClient" 说明使用的是Oracle数据库 providerName="System.Data.Oracle.DataAccess.Client" 同上,Oracle数据库 providerName="System.Data.OleDb" 说明使用的是Access数据库 --> </connectionStrings> </configuration>
连接数据库的写法,这里只是把数据打印出来,没有做任何操作:
private static void SqlConnPrint() { StringBuilder sb = new StringBuilder("姓名\t学号\t年龄\t性别\n"); //第一步:读取配置文件 string str = ConfigurationManager.ConnectionStrings["constr"].ToString(); //string str = @"Data Source=ANAN\SQLEXPRESS;Initial Catalog=student;Persist Security Info=True;"; //第二步:创建数据库连接对象conn using (SqlConnection conn = new SqlConnection(str)) { //第三步:打开数据库 conn.Open(); //第四步:创建执行sql语句的cmd对象 using (SqlCommand cmd = conn.CreateCommand()) { //第五步:构建要执行的sql语句 cmd.CommandText = "select * from student"; //第六步:执行sql语句,拿到reader对象 using (SqlDataReader reader = cmd.ExecuteReader()) { //第七步:读取数据 while (reader.Read()) { sb.Append(reader.GetString(reader.GetOrdinal("sname")))//获取列信息的第一种方式(知道列名) .Append("\t") .Append(reader["sno"])//第二种方式(知道列名) .Append("\t") .Append(reader[2])//第三种方式(列的知道位置,即第几列) .Append("\t") .Append(reader.GetString(reader.GetOrdinal("ssex"))) .Append("\n"); } Console.WriteLine(sb); } } } }
打印的结果:
总结下使用SqlDataReader时应该注意以下几点:
- SqlDataReader对象维持了一个指针,该指针最开始指向的是结果集中的第一个元组,每次调用Reader()方法都会向下挪动指针,Reader()方法返回true则说明下面还有元组,返回false说明已经读到了最后一个元组了,这个指针只能向下挪动,不能回头;
- SqlDataReader对象只能读数据,不能写数据;
- 一个SqlDataConnection只能被一个SqlDataReader对象使用,不能两个reader对象使用同一个conn对象;
- 使用完毕尽量显示调用Close()方法,虽然使用using代码块会自动帮你关闭;
- 如果要在SqlDataReader对象还未读取完所有的结果集就要关闭SqlDataReader对象,则一个先调用Command对象的Cancel()方法,然后再显示调用SqlDataReader对象的Close()方法。
做个一个测试,SqlDataReader是否每次调用Reader()方法都会去数据库中读取,结果是没有,它是将数据读到一个缓冲区,然后一行一行读取这个缓冲区,所以最上面的表格中说一行行的读取元组并不准确。
代码上来先:
public static void ProveSqlDataReader() { String connStr = ConfigurationManager.ConnectionStrings["connStr"].ToString(); SqlConnection conn = new SqlConnection(connStr); SqlConnection conn2 = new SqlConnection(connStr); conn.Open(); conn2.Open(); SqlCommand cmd = new SqlCommand("select * from student", conn); SqlCommand cmd2 = new SqlCommand("delete student;", conn2); SqlDataReader reader = cmd.ExecuteReader(); cmd2.ExecuteNonQuery();//这里将数据库中的数据全删除了,但是还是打印输出了数据表中的数据。 while (reader.Read()) { Console.WriteLine("数据: " + reader[0]); } conn.Close(); conn2.Close(); }
有关于DataSet相关的请看下一篇博客