在刚弄好登录的时候,姐夫帮忙看了后,提醒我有漏洞,我也想起了以前老师也讲过的SQL注入,例如
string sql = string.Format("SELECT COUNT(*) FROM demoUsers WHERE UserName='{0}' AND UserPassword = '{1}'", textBox1.Text.Trim(), textBox2.Text.Trim());
那么可以在登录框中输入:XXX' or 1==1--,这边是漏洞,于是就有了接下来参数化sql语言的修改。
1 //新建查询语句 2 string sql = string.Format("SELECT COUNT(*) FROM demoUsers WHERE UserName=@UserName AND UserPassword = @UserPassword"); 3 SqlCommand command = new SqlCommand(sql, sqlHelp.connection); 4 //打开数据库连接 5 sqlHelp.connection.Open(); 6 command.Parameters.AddWithValue("@UserName", textBox1.Text.Trim()); //参数化Sql语句 7 command.Parameters.AddWithValue("@UserPassword", textBox2.Text.Trim()); 8 num = Convert.ToInt32(command.ExecuteScalar());//执行查询并返回查询结果
此上是自己的一个例子,那么是查询本数据库中而不是用户输入的便是下面此法:
例如我们在本篇中创建的表UserInfo中查找所有女性用户,那么通常情况下我们的SQL语句可能是这样:
select * from UserInfo where sex=0
在参数化SQL语句中我们将数值以参数化的形式提供,对于上面的查询,我们用参数化SQL语句表示为:
select * from UserInfo where sex=@sex
再对代码中对这个SQL语句中的参数进行赋值,假如我们要查找UserInfo表中所有年龄大于30岁的男性用户,这个参数化SQL语句可以这么写:
select * from UserInfo where sex=@sex and age>@age
下面是执行这个查询并且将查询结果集以DataTable的方式返回的代码:
1 //实例化Connection对象 2 SqlConnection connection = new SqlConnection("server=localhost;database=pubs;uid=sa;pwd=''"); 3 //实例化Command对象 4 SqlCommand command = new SqlCommand("select * from UserInfo where sex=@sex and age>@age", connection); 5 //第一种添加查询参数的例子 6 command.Parameters.AddWithValue("@sex", true); 7 //第二种添加查询参数的例子 8 SqlParameter parameter = new SqlParameter("@age", SqlDbType.Int);//注意UserInfo表里age字段是int类型的 9 parameter.Value = 30; 10 command.Parameters.Add(parameter);//添加参数 11 //实例化DataAdapter 12 SqlDataAdapter adapter = new SqlDataAdapter(command); 13 DataTable data = new DataTable();
上面的代码是访问SQL Server数据库的代码。如果本文中提到的数据分别在Access、MySQL、Oracle数据库,那么对应的参数化SQL语句及参数分别如下:
数据库 | Access | MySQL | Oracle |
SQL语句 | select * from UserInfo where sex=? and age>? |
select * from UserInfo where sex=?sex and age>?age |
select * from UserInfo where sex=:sex and age>:age |
参数 | OleDbParameter | MySqlParameter | OracleParameter |
实例化参数 | OleDbParameter p=new OleDbParameter(“?”, OleDbType. Boolean); | MySqlParameter p=new MySqlParameter(“?sex”, MySqlDbType.Bit); | OracleParameter p=new OracleParameter(“:sex”, OracleType.Byte); |
赋值 | p.Value=true; | p.Value=1; | p.Value=1; |
参考来源:http://www.cnblogs.com/aito/archive/2010/08/25/1808569.html
http://www.cnblogs.com/lzrabbit/archive/2012/04/21/2460978.html
每天小知识点归纳:
1.数据库有bit类型,可记录性别true与false.在运用中也就是1.0。
2.命名空间跨文档引用的时候记得命名空间的using。
3.catch的使用,可以在前面定义error,之后后面的判断可以为if(num ==1&&error==false)
1 try 2 { 3 //新建查询语句 4 //打开数据库连接 5 catch (Exception ex) 6 { 7 MessageBox.Show(ex.Message ); 8 } 9 finally 10 { 11 sqlHelp.connection.Close(); 12 }