C#数据库教程3-ADO.NET其它优化功能

8 篇文章 3 订阅

目录

一、数据库语句注入漏洞

1、普通sql语句方式查询

2、防注入漏洞的SQL查询

二、DataSet离线数据集

三、连接字符串放到配置文件中

1、配置文件添加和编辑

 2、配置文件字符串在程序中使用

 工程代码


一、数据库语句注入漏洞

以查询语句举例,在textbox文本框中输入查询内容执行数据库查询。

1、普通sql语句方式查询

代码:

        private void btnSqlRead1_Click(object sender, EventArgs e)
        {
            try
            {
                //SqlConnection为建立和数据库连接得对象
                using (SqlConnection conn = new SqlConnection("Data Source=127.0.0.1; Initial Catalog=MyTest;User=sa;Password=54085408"))
                {
                    conn.Open();    //打开连接
                    //通过连接创建一个向数据数据库发送命令(Command)得对象SqlCommand
                    using (SqlCommand cmd = conn.CreateCommand())
                    {
                        //CommandText为要执行得sql语句
                        //cmd.CommandText = "select Age from tbl_student where Name='pan'";
                        cmd.CommandText = "select Age from tbl_student where Name='" + txtSqlInput.Text + "'";
                        using (SqlDataReader rd = cmd.ExecuteReader())
                        {
                            while (rd.Read())
                            {
                                int age = rd.GetInt32(0);                                                 
                                MessageBox.Show( age.ToString());
                            }
                        }
                    }
                }
            }
            catch { }
        }

界面

数据库

测试1:输入正常得查询字符

普通sql语句是怎么造成数据注入漏洞得

输入:pan

测试2:输入特殊得拼接字符

输入 :1' or '1'='1

发现将每一个结果都显示出来

 原因:输入得1' or '1'='1字符和程序内部得SQL语句拼接形成了SQL语句,使用断点调试发现新得SQL语句变为:select Age from tbl_student where Name=' 1' or '1'='1'

 因为or '1'='1'条件始终满足,所以while条件一直都满足,因此把数据库中所以得数据都查询了出来。

2、防注入漏洞的SQL查询

方法:将要查询的字段的使用符号 @。(数据库的表名、字段名或者其它特殊的在sql语句或者select旁边的字段也不能使用@)

代码

private void btnSqlRead2_Click(object sender, EventArgs e)
        {
            try
            {
                //SqlConnection为建立和数据库连接得对象
                using (SqlConnection conn = new SqlConnection("Data Source=127.0.0.1; Initial Catalog=MyTest;User=sa;Password=54085408"))
                {
                    conn.Open();    //打开连接
                    //通过连接创建一个向数据数据库发送命令(Command)得对象SqlCommand
                    using (SqlCommand cmd = conn.CreateCommand())
                    {
                        //CommandText为要执行得sql语句      
                        //cmd.CommandText = "select Age from tbl_student where Name=@name or Age>@age";
                        //cmd.Parameters.Add(new SqlParameter("@age", 100));

                        //cmd.Parameters.AddWithValue("@name", txtSqlInput2.Text);
                        cmd.CommandText = "select Age from tbl_student where Name=@name";                        
                        cmd.Parameters.Add(new SqlParameter("@name", txtSqlInput2.Text));
                        using (SqlDataReader rd = cmd.ExecuteReader())
                        {
                            while (rd.Read())
                            {
                                int age = rd.GetInt32(0);
                                MessageBox.Show(age.ToString());
                            }
                        }
                    }
                }
            }
            catch { }
        }

界面

 数据库

 测试

(1)输入1' or '1'='1,查询不再将数据库中数据弹出

(2)输入pan,查询出结果

其它语句如:

insert into ......  values(@name,@age)

delete .......where Id=@id

二、DataSet离线数据集

SqlDataReader是连接相关的,SqlDataReader中的查询结果并不是放到程序中的,而是在数据库服务器中,SqlDataReader只是相当于放了一个指针(游标),只能读取当前游标指向的行,一旦连接断开就不能再读取。这样做的好处就是无论查询结果有多少条,对程序占用的内存都几乎没有影响。

SqlDataReader对于小数据量的数据来说带来的只有麻烦。ADO.NET中提供了数据集的机制,将查询结果填充到本地内存中,这样连接断开、服务器断开都不影响数据的读取。数据集的好处是降低数据库服务器压力、编程也简单。

测试代码:

        private void btnDataSetRead_Click(object sender, EventArgs e)
        {
            try
            {
                 //SqlConnection为建立和数据库连接得对象
                using (SqlConnection conn = new SqlConnection("Data Source=127.0.0.1; Initial Catalog=MyTest;User=sa;Password=54085408"))
                {
                    conn.Open();    //打开连接
                    //通过连接创建一个向数据数据库发送命令(Command)得对象SqlCommand
                    using (SqlCommand cmd = conn.CreateCommand())
                    {
                        cmd.CommandText = "select * from tbl_student where Age<@age";
                        cmd.Parameters.Add(new SqlParameter("@age", 100));

                        //SqlDataAdapter是一个帮我们把SqlCommand查询结果填充到DataSet中的类
                        SqlDataAdapter adapter = new SqlDataAdapter(cmd);
                        //DataSet相当于本地的一个复杂集合List<...>
                        DataSet dataset = new DataSet();
                        adapter.Fill(dataset);      //执行cmd,并且把SqlCommand查询结果填充到DataSet

                        DataTable table = dataset.Tables[0];            //dataset可以有很多个表
                        DataRowCollection rows = table.Rows;
                        for(int i=0;i<rows.Count;i++)
                        {
                            DataRow row = rows[i];
                            int age = (int)row["Age"];
                            string name = (string)row["Name"];
                            string comment = (string)row["Comment"];
                            MessageBox.Show(name + "," + age.ToString() + "," + comment);
                        }
                    }
                }
            }
            catch { }
        }

数据库数据

程序运行测试

依次跳出各个查询结果

三、连接字符串放到配置文件中

1、配置文件添加和编辑

 将连接数据库的用户名、密码、数据库ip地址等放到配置文件中,方便用户在使用的时候方便修改。新创建的winform程序中自动添加App.config文件。如果没有的话,手动添加。

 (1)手动添加配置文件

(2)双击打开配置文件

(3)修改配置文件,编译运行。

(4) 用户在使用时,在根目录下打开配置文件修改

(4) 修改程序工程中的,工程之间复制或者拷贝。然后工程再重新编译、生成

 2、配置文件字符串在程序中使用

(1)在引用中添加程序集System.Configuration

 (2)添加按钮事件程序,将配置文件中的字符串读出来

程序

using System.Configuration;

        private void btnTestConnectString_Click(object sender, EventArgs e)
        {
            string connString = ConfigurationManager.ConnectionStrings["dbConnstr"].ConnectionString;
            MessageBox.Show(connString);
        }

运行结果

 (3)修改上一个DataSet程序

修改前代码

         private void btnDataSetRead_Click(object sender, EventArgs e)
        {
            try
            {
                 //SqlConnection为建立和数据库连接得对象
                using (SqlConnection conn = new SqlConnection("Data Source=127.0.0.1; Initial Catalog=MyTest;User=sa;Password=54085408"))
                {
                    conn.Open();    //打开连接
                    //通过连接创建一个向数据数据库发送命令(Command)得对象SqlCommand
                    using (SqlCommand cmd = conn.CreateCommand())
                    {
                        cmd.CommandText = "select * from tbl_student where Age<@age";
                        cmd.Parameters.Add(new SqlParameter("@age", 100));

                        //SqlDataAdapter是一个帮我们把SqlCommand查询结果填充到DataSet中的类
                        SqlDataAdapter adapter = new SqlDataAdapter(cmd);
                        //DataSet相当于本地的一个复杂集合List<...>
                        DataSet dataset = new DataSet();
                        adapter.Fill(dataset);      //执行cmd,并且把SqlCommand查询结果填充到DataSet

                        DataTable table = dataset.Tables[0];            //dataset可以有很多个表
                        DataRowCollection rows = table.Rows;
                        for(int i=0;i<rows.Count;i++)
                        {
                            DataRow row = rows[i];
                            int age = (int)row["Age"];
                            string name = (string)row["Name"];
                            string comment = (string)row["Comment"];
                            MessageBox.Show(name + "," + age.ToString() + "," + comment);
                        }
                    }
                }
            }
            catch { }
        }

修改后代码

        private void btnTestConnectString_Click(object sender, EventArgs e)
        {            
            try
            {
                string connString = ConfigurationManager.ConnectionStrings["dbConnstr"].ConnectionString;
                //SqlConnection为建立和数据库连接得对象
                using (SqlConnection conn = new SqlConnection(connString))
                {
                    conn.Open();    //打开连接
                    //通过连接创建一个向数据数据库发送命令(Command)得对象SqlCommand
                    using (SqlCommand cmd = conn.CreateCommand())
                    {
                        cmd.CommandText = "select * from tbl_student where Age<@age";
                        cmd.Parameters.Add(new SqlParameter("@age", 100));

                        //SqlDataAdapter是一个帮我们把SqlCommand查询结果填充到DataSet中的类
                        SqlDataAdapter adapter = new SqlDataAdapter(cmd);
                        //DataSet相当于本地的一个复杂集合List<...>
                        DataSet dataset = new DataSet();
                        adapter.Fill(dataset);      //执行cmd,并且把SqlCommand查询结果填充到DataSet

                        DataTable table = dataset.Tables[0];            //dataset可以有很多个表
                        DataRowCollection rows = table.Rows;
                        for (int i = 0; i < rows.Count; i++)
                        {
                            DataRow row = rows[i];
                            int age = (int)row["Age"];
                            string name = (string)row["Name"];
                            string comment = (string)row["Comment"];
                            MessageBox.Show(name + "," + age.ToString() + "," + comment);
                        }
                    }
                }
            }
            catch { }

        }

 测试

将生成的Debug程序拷贝到虚拟机中的win7系统环境下运行,config中修改ip地址

 工程代码

https://download.csdn.net/download/panjinliang066333/85153786

创作不易,请多多支持

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Big_潘大师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值