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
    评论
前面做项目,有数据库操作太慢。 而且,有一些新的程序员,他们对数据库操作的经验比较欠缺, 而且,.net需要学的东西就非常多,涵盖很多,还要程序员精通数据库,就更加麻烦,没有好多年的经验, 操作数据库的,一检查就有很多问题。所以,根据需要,我就找到了这个 简单的,高效,快速,方便的 .net数据库操作方案。非常直观。不需要懂数据库都能开发了。 找了好久,总算找到了,分享给大家。 ---------------------------- ------------------------------ SqLamdalf1.0 ----------================-----------================--------- .net数据库最佳操作类。 无缝衔接sql server和.net。 不需要为操作数据库再话费大量的开发时间,节约开发成本,以及更高效,更快速,更方便。 以后将陆续支持更多的数据库。 ----------================-----------================--------- SqLamdalf1.0免费版,欢迎使用。 使用方法: 双击setup.exe 安装以后。 桌面会出现 SqLamdalf 然后直接添加到需要的程序引用中,就可以使用了。 ============================================================== 调用方法: using SqlLamdalf; //工厂方法建立连接字符串 SqlLamdalf.FactoryAnna factorySql = new SqlLamdalf.FactoryAnna(AnnaType.SqlServer, "Persist Security Info=False;Integrated Security=SSPI;Database=数据库名称;Server=sql服务器名称"); //对需要的表的对象建立对象Sql。下面例子中为两个表,目前已经支持9个表: var Sql = factorySql.Create(); //目前支持返回 1实体类Sql.ExecuteEntity,2实体类列表,3表格,4字符串,5int var sdfsf123 = Sql.ExecuteList((a, b) => Sub.Top(8).Select(a.UserId, a.UserName).From(a) ); //目前支持返回 1实体类Sql.ExecuteEntity,2实体类列表,3表格,4字符串,5int var sdfsf123 = Sql.ExecuteList((a, b) => Sub.Top(8).Select(a.UserId, a.UserName).From(a) ); //分页查询如下,注意OrderBy免费版请取消 DataTable dtUser = Sql.ExecuteDataTable((a, b) => Sub.PageSize(12).PageIndex(2).Select(a.UserId.As("ID号"), a.UserName.As("名字")).From(a).OrderBy(a.CreateDate.Desc()) ); //如需执行多条语句,请在语句后面加上Next() var sdfsf1113 = Sql.ExecuteList((a, b) => Sub.Insert(a).Values("213", "111", 11, "2012-02-02"). Next(). Select("213", "111", 11, "2012-02-02").From(a).Where(a.UserId == 123123) ); //下面是联结方式的多表查询,支持各种联结查询,&&意味and,LikeLeft意为Like '%name',LikeRight var sdfsf21 = Sql.ExecuteNonQuery((a, b) => Sub.Update(a).Set(a.RoleId == u1.RoleId, a.LoginPassword == irod.ToString(), a.UserName == "2").From(a). InnerJoin(b).On(a.UserId == b.CategoryId) .Where(a.UserId == 1 && (a.UserName + "123").LikeLeft(u1.UserName)) );

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Big_潘大师

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

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

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

打赏作者

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

抵扣说明:

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

余额充值