查询和操作数据库

  要想从数据库中读取多条记录就必须用到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();

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();

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

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

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

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();

上面的修改,是用了其试占位符的字段,来赋值,不是用参数的形式来设值,这样子就堵注了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("用户名不存在");
                   }
                  
               }
           
           }

}

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

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

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

ADO.NET基础02的更多相关文章

  1. ADO.NET基础02(语句参数化,配置文件,DataSet与DataTable)

    ADO.NET连接池 ado.net默认启用了连接池 *如何清空连接池?Connection的静态方法ClearAllPools(). ClearPool() Ado.net连接池使用总结: 1.第一 ...

  2. javascript基础02

    javascript基础02 1.数据类型 数据类型的描述在上篇的扩展中有写到链接 由于ECMAScript数据类型具有动态性,因此的确没有再定义其他数据类型的必要.这句话很重要. 如果以后再数据类型 ...

  3. javaSE基础02

    javaSE基础02 一.javac命令和java命令做什么事情? javac:负责编译,当执行javac时,会启动java的编译程序,对指定扩展名的.java文件进行编译,生成了jvm可以识别的字节 ...

  4. ADO.NET基础03

    数据库和VS的连接,实现数据的同步,让用户的一切信息都可以在数据库中留下记录. ADO.NET基础      它是连接所有数据库的一种特殊的技术,提供对不同的数据库统一操作接口. 在VS中也可以添加数 ...

  5. java基础学习05(面向对象基础02)

    面向对象基础02 实现的目标 1.String类的使用2.掌握this关键字的使用3.掌握static关键字的使用4.了解内部类 String类 实例化String对象一个字符串就是一个String类 ...

  6. .Net Core 系列:2、ADO.Net 基础

    目录: 1.环境搭建 2.ADO.Net 基础 3.ASP.Net Core 基础 4.MD5.Sha256.AES 加密 5.实现登录注册功能 6.实现目录管理功能 7.实现文章发布.编辑.阅览和删 ...

  7. 有关ADO.NET基础中的基础的熟悉过程

    现在对于ADO.NET基础的理解与记忆并不严谨和完善 所以,只写一点关于自己的理解,嗯,一种去转换思维理解的方法吧,算是吧 希望各位前辈或者同学,积极指出其中的错误和偏差 个人对于刚接触的ADO.NE ...

  8. 如鹏网学习笔记(六)ADO.Net基础

    ADO.Net基础 一.ADO.Net简介 1,程序要通过SQL语句自动化的操作数据库,必须要用一个类库, 类库要提供execute("insert into ...")/exec ...

  9. ADO.NET基础开发

    ADO.NET是微软新一代.NET数据库的访问架构,ADO是ActiveX Data Objects的缩写.ADO.NET是数据库应用程序和数据源之间沟通的桥梁,主要提供了一个面向对象的数据访问架构, ...

随机推荐

  1. 作业二:Github注册过程

    第一步.打开Github官网https://github.com/ ,在相应位置填写注册名.注册邮箱.注册密码完成后点击注册. 第二步.这时会弹出一个界面,让你选择你的私人计划(personal pl ...

  2. java提高篇(二十)-----集合大家族

          在编写java程序中,我们最常用的除了八种基本数据类型,String对象外还有一个集合类,在我们的的程序中到处充斥着集合类的身影!java中集合大家族的成员实在是太丰富了,有常用的Arra ...

  3. 一个老菜鸟所理解的UX及产品流

    从事前端开发到目前为止已经有4年多的时间了,从一个小菜鸟一路依靠自学,到目前总算一个老菜鸟了.当然了,从事前端的工作,是免不了要对产品以及用户体验有些许了解的.最近谈论起这方面的内容,就按照自己的想法 ...

  4. Android Instrumention.sendPointerSync发送Event失败分析

    问题场景 Android4.3,进入被测app某个Activity后,测试案例ClickOnScreen出现异常(Click can not be completed!). Android4.4正常. ...

  5. IBatisNet:让insert操作返回新增记录的主键值

    项目引用ibatis包: IBatisNet.Common.dll --文件版本1.6.2.0 IBatisNet.DataAccess.dll IBatisNet.DataMapper.dll 项目 ...

  6. js中setTimeout()的使用bug

    今天用setTimeout()时,遇到一个奇怪的现象,通过多方面的查询,最终解决了问题,这是setTimeout()设计的时候存在的一点点bug. 代码的作用主要是在三秒后自动关闭本浏览器窗口: 代码 ...

  7. Node.js与Sails~方法拦截器policies

    回到目录 policies sails的方法拦截器类似于.net mvc里的Filter,即它可以作用在controller的action上,在服务器响应指定action之前,对这个action进行拦 ...

  8. 国内常用的三种框架:ionic/mui/framework7对比

    国内常用的三种框架:ionic/mui/framework7对比 原文连接:http://zhihu.com/question/19558750/answer/91179040

  9. 手机页面的 HTML<meta> 标签使用与说明

    name="viewport" 设置窗口(网页可绘制的区域) width="device-width" 应用宽与屏幕的宽一样的 (height同width) i ...

  10. 如何制作自己的yum源

    在 /etc/yum.repos.d下创建一个以.repo结尾的文件如aaa.repo,其内容如下(一定要以repo结尾)   [aaa] name=aaa baseurl=http://mirror ...