一、sql注入风险及解决方案
SQL注入是指在事先定义好的SQL语句中注入额外的SQL语句,从此来欺骗数据库服务器的行为。
示例:制作会员登录功能。
二、防止sql注入解决方案
- 使用参数化查询
- 使用ORM框架 Entity Framework可以自动处理SQL查询的安全性
使用参数化查询
cs
private void btLogin_Click(object sender, EventArgs e)
{
// 定义数据库连接字符串
string conStr = "server=.;database=adoNet;uid=sa;pwd=123456";
// 创建SqlConnection对象并初始化连接字符串
SqlConnection conn = new SqlConnection(conStr);
// 打开数据库连接
conn.Open();
// 定义SQL查询语句,并使用参数化查询防止SQL注入
string sql = " select * from Member where MemberAccount = @MemberAccount and MemberPwd = @MemberPwd";
// 创建一个SqlDataAdapter对象,用于填充DataTable
SqlDataAdapter adapter = new SqlDataAdapter(sql, conn);
// 向SelectCommand中添加参数,将文本框中的值作为参数值传递
adapter.SelectCommand.Parameters.Add(new SqlParameter("@MemberAccount", this.textAccount.Text));
adapter.SelectCommand.Parameters.Add(new SqlParameter("@MemberPwd", this.textPwd.Text));
// 创建一个新的DataTable实例
DataTable dt = new DataTable();
// 使用SqlDataAdapter的Fill方法填充DataTable
adapter.Fill(dt);
if (dt.Rows.Count > 0)
MessageBox.Show("登录成功");
else
MessageBox.Show("登录失败");
}
cs
string sql ="INSERT INTO Member (MemberAccount, MemberPwd, MemberName, MemberPhone)VALUES" +
" (@MemberAccount ,@MemberPwd ,@MemberName ,@MemberPhone )";
//****执行sql语句******
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add(new SqlParameter("@MemberAccount", this.textAccount.Text));
cmd.Parameters.Add(new SqlParameter("@MemberPwd", this.textPwd.Text));
cmd.Parameters.Add(new SqlParameter("@MemberName", this.textName.Text));
cmd.Parameters.Add(new SqlParameter("@MemberPhone", this.textIphone.Text));
int code = cmd.ExecuteNonQuery();
三、封装DBHelper类
- 代码重用
- 提高可读性和可维护性
- 遵循单一职责原则
- 安全性参数化查询
cs
internal class DBHelper
{
// 连接字符串,包含服务器地址、数据库名称、用户名和密码
public static string strConn = "server=.;database=adoNet;uid=sa;pwd=123456";
// 数据库连接对象,用于与数据库建立连接
public static SqlConnection conn = null;
// 数据适配器,用于执行 SQL 命令并填充数据集
public static SqlDataAdapter adp = null;
/// <summary>
/// 打开数据库连接
/// </summary>
public static void OpenConn()
{
if (conn == null)
{
// 如果连接对象为空,则创建一个新的连接对象并打开连接
conn = new SqlConnection(strConn);
conn.Open();
}
if (conn.State == System.Data.ConnectionState.Closed)
{
// 如果连接已关闭,则重新打开连接
conn.Open();
}
if (conn.State == System.Data.ConnectionState.Broken)
{
// 如果连接状态为断开,则先关闭再重新打开连接
conn.Close();
conn.Open();
}
}
/// <summary>
/// 准备 SQL 语句,包括打开数据库连接和创建数据适配器
/// </summary>
/// <param name="sql">要执行的 SQL 语句</param>
public static void PrepareSql(string sql)
{
OpenConn(); // 打开数据库连接
adp = new SqlDataAdapter(sql, conn); // 创建数据适配器并设置 SQL 语句和连接对象
}
/// <summary>
/// 设置 SQL 语句的参数
/// </summary>
/// <param name="paramenterName">参数名称</param>
/// <param name="paramenterValue">参数值</param>
public static void SetParamenter(string paramenterName, object paramenterValue)
{
if (paramenterValue == null)
{
// 如果参数值为 null,则将其转换为 DBNull.Value
paramenterValue = DBNull.Value;
}// 添加参数到 SQL 命令中
adp.SelectCommand.Parameters.Add(new SqlParameter(paramenterName, paramenterValue));
}
/// 执行非查询 SQL 语句(如 INSERT、UPDATE、DELETE)
public static int ExecNonQuery()
{
int count = adp.SelectCommand.ExecuteNonQuery(); // 执行 SQL 命令并返回受影响的行数
conn.Close(); // 关闭数据库连接
return count;
}
/// 执行查询 SQL 语句并返回数据表
public static DataTable ExceQuery()
{
DataTable dt = new DataTable(); // 创建一个新的数据表
adp.Fill(dt); // 使用数据适配器填充数据表
return dt; // 返回数据表
}
// 执行查询 SQL 语句并返回 DataReader 对象
//<returns>包含查询结果的 DataReader 对象</returns>
public static SqlDataReader ExcuDataReader()
{// 执行 SQL 命令并返回 DataReader 对象,同时设置关闭连接的行为
return adp.SelectCommand.ExecuteReader(CommandBehavior.CloseConnection);
}
/// <summary>
/// 执行查询 SQL 语句并返回单个值
/// </summary>
/// <returns>查询结果的第一个值</returns>
public static Object ExecuteScalar()
{
Object obj = adp.SelectCommand.ExecuteScalar(); // 执行 SQL 命令并返回第一个值
conn.Close(); // 关闭数据库连接
return obj; // 返回查询结果
}
}
cs
private void button1_Click(object sender, EventArgs e)
{ //准备sql语句
string sql = "INSERT INTO Member (MemberAccount, MemberPwd, MemberName, MemberPhone)VALUES" +
" (@MemberAccount ,@MemberPwd ,@MemberName ,@MemberPhone )";
DBHelper.PrepareSql(sql);
//传参数
DBHelper.SetParamenter("@MemberAccount", this.textAcount.Text);
DBHelper.SetParamenter("@MemberPwd", this.textPwd.Text);
DBHelper.SetParamenter("@MemberName", this.textName.Text);
DBHelper.SetParamenter("@MemberPhone", this.textIphone.Text);
//执行
DBHelper.ExecNonQuery();
}