有没有更有效的方法来编写此 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张表:

  1. disease_table [列=] (disease_id,disease_name)
  2. symptom_table [列=] (symptom_id,symptom_name)
  3. disease_symptom [列=] (disease_id,symptom_id)

我的网页上有一个复选框列表,其中有症状,文本=发烧,值='发烧'。依此类推,这样做的原因是用户可以选择任意数量的复选框,并且在子句中不接受参数

有没有更有效的方法来编写此 SQL 代码

与注释中的建议相反,您不需要存储过程来防止 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) + ")"; 

基本上,您不注入值,而是为查询注入参数。参数名称是在代码中生成的,因此它们不会被弄乱。在执行查询之前,驱动程序会清理参数的值,因此这些值也不会被弄乱。