zoukankan      html  css  js  c++  java
  • SQL Server数据库读取数据的DateReader类及其相关类

    之前学了几天的SQL Server,现在用C#代码连接数据库了。

    需要使用C#代码连接数据库,读取数据。

    涉及的类有:

    1. ConfigurationManage
    2. SqlConnection
    3. SqlCommand
    4. 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=ANANSQLEXPRESS;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("姓名	学号	年龄	性别
    ");
                //第一步:读取配置文件
                string str = ConfigurationManager.ConnectionStrings["constr"].ToString();
                //string str = @"Data Source=ANANSQLEXPRESS;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("	")
                                    .Append(reader["sno"])//第二种方式(知道列名)
                                    .Append("	")
                                    .Append(reader[2])//第三种方式(列的知道位置,即第几列)
                                    .Append("	")
                                    .Append(reader.GetString(reader.GetOrdinal("ssex")))
                                    .Append("
    ");
                            }
                            Console.WriteLine(sb);
                        }
                    }
                }
            }

    打印的结果:

    2

    总结下使用SqlDataReader时应该注意以下几点:

    1. SqlDataReader对象维持了一个指针,该指针最开始指向的是结果集中的第一个元组,每次调用Reader()方法都会向下挪动指针,Reader()方法返回true则说明下面还有元组,返回false说明已经读到了最后一个元组了,这个指针只能向下挪动,不能回头;
    2. SqlDataReader对象只能读数据,不能写数据;
    3. 一个SqlDataConnection只能被一个SqlDataReader对象使用,不能两个reader对象使用同一个conn对象;
    4. 使用完毕尽量显示调用Close()方法,虽然使用using代码块会自动帮你关闭;
    5. 如果要在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相关的请看下一篇博客

    模拟在内存中的数据库DataSet相关类

    【点击此处回到主页】

  • 相关阅读:
    CodeForces.1174D.EhabandtheExpectedXORProblem(构造前缀异或和数组)
    HDU-6187.DestroyWalls(最大生成树)
    HDU.6186.CSCource.(前缀和数组和后缀和数组)
    <每日一题>Day 9:POJ-3281.Dining(拆点 + 多源多汇+ 网络流 )
    <每日一题> Day8:CodeForces-996A.Hit the Lottery(贪心)
    最小割 + 网络流变体
    <每日一题> Day7:CodeForces-1166C.A Tale of Two Lands (二分 + 排序)
    <每日一题> Day6:HDU递推专题完结
    <每日一题> Day5:简单递推两题
    POJ-3122.Pie(二分法最大化平均值)
  • 原文地址:https://www.cnblogs.com/daimajun/p/6531507.html
Copyright © 2011-2022 走看看