有没有更有效的方法来编写此 SQL 代码
本文关键字:SQL 代码 有效 方法 有没有 | 更新日期: 2023-09-27 18:34:11
protected void Button1_Click(object sender, EventArgs e)
{
MySqlConnection connection = new MySqlConnection(ConfigurationManager.ConnectionStrings["myconstring"].ConnectionString);
connection.Open();
symptons = String.Join(", ", CheckBoxList1.Items.Cast<ListItem>().Where(i => i.Selected).Select(i => i.Value).ToArray());
Label3.Text = symptons;
if(symptons!="")
{
MySqlCommand cmd = new MySqlCommand("select d.dname from disease d inner join diseasesymptom ds on ds.did = d.did inner join symptom s on s.sid = ds.sid where s.sname in (" + symptons + ")", connection);
using (MySqlDataAdapter sda = new MySqlDataAdapter())
{
cmd.Connection = connection;
sda.SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
}
else
{
Label2.Text = "select at least one symptom";
}
}
我知道我正在自己的代码上执行sql注入,所以我如何防止这种情况,基本上有3张表:
- disease_table [列=] (disease_id,disease_name)
- symptom_table [列=] (symptom_id,symptom_name)
- disease_symptom [列=] (disease_id,symptom_id)
我的网页上有一个复选框列表,其中有症状,文本=发烧,值='发烧'。依此类推,这样做的原因是用户可以选择任意数量的复选框,并且在子句中不接受参数
与注释中的建议相反,您不需要存储过程来防止 SQL 注入。可以使用参数化查询来执行此操作。
以下代码应完成这项工作:
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = connection;
List<string> names = new List<string>();
for (int i = 0; i < symptons.Length; i++)
{
names.Add("@Param_" + i);
cmd.Parameters.Add(new MySqlParameter("@Param_" + i, symptons[i]));
}
cmd.CommandText = "select d.dname from disease d inner join diseasesymptom ds on ds.did = d.did inner join symptom s on s.sid = ds.sid where s.sname in (" + string.Join(",", names) + ")";
基本上,您不注入值,而是为查询注入参数。参数名称是在代码中生成的,因此它们不会被弄乱。在执行查询之前,驱动程序会清理参数的值,因此这些值也不会被弄乱。