• ADO.NET基础02


    查询和操作数据库

      要想从数据库中读取多条记录就必须用到Command对象的ExecuteReader()方法,该方法返回一个DataReader对象,通过其对象的程序就可以访问数据库。

    基础知识

    conn.close();   //关闭之后还能打开;

    conn.dispose();  //直接销毁不能再次利用,dispose内部有close方法;

        

    认识DataReader对象

            使用其DataReader对象可以从数据库中检索只读数据,且每次只能从查询结果中读取一行到内存中,非常的快,使用其时不能对其进行修改,只能读取。而且在读取是一定要与数据库连接,不能断开连接。

    要创建一个DataReader对象需要调用Command对象的ExecuteRead()方法,此方法返回值就是一个DataReader对象,之后调用其对象的Reader()方法来读取一行数据,{将其放在一个while循环中,这样就可以将所有的值全部都显示出来}

    步骤:

    1:创建Command对象

         string connSting=”Data Source=zhanghui; Initial Catalog=Ahui; User ID=sa; Pwd=111”

         sqlconnection  conn=new sqlconnection(connString);

         conn.open();

         string  sql=”saelect  count(*) from Student”;

         sqlCommand md=new sqlCommand(sql,conn);

    2:调用Command的ExecuteReader()方法创建DataReader对象。

         sqlDataReader  dataReader=md.ExecuteReader();

    3:使用其的Read()方法按行去读取数据,此方法返回一个布尔类型,若读到数据则返回true,否则返回false,此时用到了while循环。

       while(dataReader.read())

      {

          获取数据集中的值;

      }

    4:

      4.1读取当前行的某列数据,可以像数组一样进行索引,按下标进行查询显示。

            (string)dataReader[0];

      4.2还有一种方法也可以获取当前行的某列数据。

           string name=dataReader.GetString(0);                //获取其第一行的值。

    5:关闭其DataReader对象,调用其Close()方法。

    eg one : 在前台输入用户,看是否为数据库表中的数据,若是则显示成功,不是报错。

    Console.WriteLine("请输入用户名");
               string username = Console.ReadLine();
               //数据库连接字符串
               string connString = "Data Source=zhanghui;Initial Catalog=Ahui;User ID=sa;Pwd=111";
               //创建数据库的连接
               SqlConnection conn = new SqlConnection(connString);
               conn.Open();  //打开数据库
               using (SqlCommand kfc = conn.CreateCommand())                                           //创建Command对象。
               {
                   kfc.CommandText = "select * from Student where Name=  '"+username +"'  ";   //SQL语句
                   using (SqlDataReader read = kfc.ExecuteReader())
                   {
                       if (read.Read())
                       {
                           Console.WriteLine("用户存在");
                       }
                       else
                       {
                           Console.WriteLine("用户错误");
                       }

                   }
               }
               Console.WriteLine("打开数据库连接成功");
               conn.Close();        //关闭数据库,切记每次用完之后一定要关闭数据库。
               Console.ReadKey();

    wps5C9F.tmp

     

    eg two :从数据库中读取数据,显示在窗口中。

    一般的注意事项

               User是关键字,一般情况下表名以T_开头,字段以F_开头;,这样做的好处是防止表名与字段和系统的关键字重复,报错。

               reader的GenString,GetInt32等方法只能接受整数参数,也就是序号用GetOrdinal方法根据列名动态得到序号。

    特殊:  eg three :

       改变上一个登录程序,使用其count(*)来进行比较,来查看是否登录成功;

    static void Main(string[] args)
            {
                Console.WriteLine("请输入用户名");
                string username = Console.ReadLine();
                Console.WriteLine("请输入密码");
                string password = Console.ReadLine();
                //数据库连接字符串
                string connString = "Data Source=zhanghui; Initial Catalog=Ahui; User ID=sa; Pwd=111";
                //创建数据库连接
                SqlConnection conn=new SqlConnection(connString);
                //打开数据库
                conn.Open();
                using (SqlCommand  ka=conn.CreateCommand())
                {
                    ka.CommandText = "select count(*) from login where UserName='"+username+"' and  Password='"+password+"' ";

                    //当时在做的时候,不知道在UserName和Password之间加and,花费了很多的时间,最后才知道了,这是SQL语法里面的知识。   
                    int i = Convert.ToInt32(ka.ExecuteScalar());

                   //在这里的ka.ExecuteScalar()代表的就是ka.Command里面传出来的值。         

                    if (i>0)
                    {
                        Console.WriteLine("登录成功");   
                    }
                    else
                    {
                        Console.WriteLine("用户名或密码错误?");
                    }

                }
                Console.WriteLine("OK");
                Console.ReadKey();

    wpsDE7B.tmp

    但是为什么我这样子输入的话,也会出现登录成功。

    wps1499.tmp

    老师说这是一种注入漏洞,只要是登录名和数据库中的登录名一样,就可以显示登录成功。

    但是如果想避免情况的发生,就必须使用参数化查询。

    eg:

    static void Main(string[] args)
    {
        Console.WriteLine("请输入用户名");
        string username = Console.ReadLine();
        Console.WriteLine("请输入密码");
        string password = Console.ReadLine();
        //数据库连接字符串
        string connString = "Data Source=zhanghui; Initial Catalog=Ahui; User ID=sa; Pwd=111";
        //创建数据库连接
        SqlConnection conn=new SqlConnection(connString);
        //打开数据库
        conn.Open();
        using (SqlCommand  ka=conn.CreateCommand())
        {
            ka.CommandText = "select count(*) from login where UserName=@UserName and  Password=@Password";
           
    //上面的可以先看成占位符,通过下面的语句在给其赋值,。

            ka.Parameters.Add(new SqlParameter("UserName",username));

           //Parameters是其ka的一个属性,是一个集合,通过调用Add来为其上面的占位符来赋值。
            ka.Parameters.Add(new SqlParameter("Password",password));
            int i = Convert.ToInt32(ka.ExecuteScalar());
            if (i>0)
            {
                Console.WriteLine("登录成功");   
            }
            else
            {
                Console.WriteLine("用户名或密码错误?");
            }

        }
        Console.WriteLine("OK");
        Console.ReadKey();

    wps476D.tmp

    上面的修改,是用了其试占位符的字段,来赋值,不是用参数的形式来设值,这样子就堵注了SQL漏洞攻击;

    在其占位符下面在为其占位符赋值,是将拿输入的东西当成字符串的值,在数据库中进行比较,如果有则登陆成功,否则登录失败。

    ***在同一个连接中如果sqlDataReader没有关闭,那么是不能执行update之类的语句;

    下面是一个登录的实例,但是出现不了自己想要的结果,总是说出错,有谁做过可以帮我看看,谢谢。

    代码:

    /*将第二个要用的数据库连接必须重新写在一个类中,进行调用,如果在一个数据库连接字符串中
            同时进行两个sql语句的操作就会出现错误。
            这样就相当于将其封装起来,如果后面要用到,直接调用就行。
            */
           private void hui()
           {
               string connSting = "Data Source=zhanghui; Initial Catalog=Ahui; User ID=sa; Pwd=111;";
               SqlConnection conn = new SqlConnection(connSting);
               conn.Open();
               using (SqlCommand updata = conn.CreateCommand())
               {
                   updata.CommandText = "update login Set errorTimes=errorTimes+1 where UserName=@UserName ";
                   updata.Parameters.Add(new SqlParameter("UserName", txtUserName.Text));
                   updata.ExecuteNonQuery();
               }
           }

           private void btnLand_Click(object sender, EventArgs e)
           {
               string connString = "Data Source=zhanghui; Initial Catalog=Ahui; User ID=sa; Pwd=111;";
               SqlConnection conn=new SqlConnection(connString);
               conn.Open();
               using (SqlCommand lg=conn.CreateCommand())
               {
                   lg.CommandText = "select * from login where UserName=@UserName";
                   lg.Parameters.Add(new SqlParameter("UserName",txtUserName.Text));
                   using (SqlDataReader reader=lg.ExecuteReader())
                   {
                       if (reader.Read())
                       {
                           int errorTime = reader.GetInt32(reader.GetOrdinal("errorTimes"));
                           if (errorTime > 3)
                           {
                               MessageBox.Show("登陆次数过多,禁止登录!");
                               return;
                           }
                           string AhuiPassword = reader.GetString(reader.GetOrdinal("Password"));
                           if (AhuiPassword==txtPassword.Text)
                           {
                               MessageBox.Show("登陆成功");
                           }
                           else
                           {
                               hui();  //调用了本类中上面的一个类。
                               MessageBox.Show("登录失败");
                           }
                       }
                       else
                       {
                           MessageBox.Show("用户名不存在");
                       }
                      
                   }
               
               }

    }

    下面为数据库截图和登录窗口截图

    wps984B.tmp

    wpsB731.tmp

    运行结果如下,刚开始还可以运行3次,说是登录失败,现在只要是输入就说登录此数过多,求大神支招

    wpsE219.tmp

    这个问题我自己一直解决不了,困扰我了很久,希望遇到大神,帮帮我。谢了。

  • 相关阅读:
    29 练习:利用socketserver实现TCP协议下登录认证下载
    28 练习:TCP协议 UDP协议 黏包
    Python基础学习(28)TCP协议的Python实现 UDP协议的Python实现 黏包 利用struct模块解决黏包
    Python 大作业4:选课系统
    Python基础学习(27)网络编程基本概念 C/S架构与B/S架构 OSI七层协议 包的导入
    26 练习题:反射
    Python基础学习(26)classmethod/staticmethod 装饰器 部分内置魔术方法
    25 练习题:super方法 封装 property装饰器 反射
    Python基础学习笔记(25)super方法 封装 property装饰器 反射
    2020 8/10每日日报
  • 原文地址:https://www.cnblogs.com/netxiaohui/p/4175944.html
Copyright © 2020-2023  润新知