查询和操作数据库

  要想从数据库中读取多条记录就必须用到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. 【转】Backbone标准例子——通讯录

    参考:http://z2009zxiaolong.iteye.com/blog/1847833 感觉不错的例子,模型.视图.路由等知识点都用到了:),将此文中的源码转载如下: http://dmyz. ...

  2. Stealth视频教程学习笔记(第一章)

    Stealth视频教程学习笔记(第一章) 本文是对Unity官方视频教程Stealth的学习笔记.在此之前,本人整理了Stealth视频的英文字幕,并放到了优酷上.本文将分别对各个视频进行学习总结,提 ...

  3. NSString NSNumber 相互转化

    NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init]; NSNumber *firstNum = [NSNumber n ...

  4. Docker容器入门

    为什么要看docker 从去年起就或多或少的接受了docker的熏陶,主要还是Infoq在去年有很多关于docker的实践视频讲座,记得有一篇是<Docker在雪球的技术实践>,当时听的也 ...

  5. Atitit  记录方法调用参数上下文arguments

    Atitit  记录方法调用参数上下文arguments 1.1. java  java8  新的对象Parameter LocalVariableTable 本地变量表 MethodParamete ...

  6. Atitit  DbServiceV4qb9 数据库查询类库v4 新特性

    Atitit  DbServiceV4qb9 数据库查询类库v4 新特性     V4新特性 安全特性,屏蔽了executeUpdate,使用v2版 Sql异常转换,特别转换了DuplicateEnt ...

  7. atitit.vod search doc.doc 点播系统搜索功能设计文档

    atitit.vod search doc.doc 点播系统搜索功能设计文档 按键的enter事件1 Left rig事件1 Up down事件2 key_events.key_search = fu ...

  8. 事件异步(EAP)使用事件异步处理一些耗时操作

    比如需要下载一些比较大的文件,如果使用会UI卡顿,使用异步可以节省一些时间 下面是一些例子: using System; using System.Collections.Generic; using ...

  9. Lock VS Monitor

    Lock Monitor   多线程操作的时候,为防止死锁,我们经常采用加Lock的方式解决,下面就谈一下Lock的具体运用和Lock可以用什么来替换 首先,看代码: private static o ...

  10. JQ动画的简单介绍

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>j ...