删除按钮太慢了是什么问题

时间:2019-01-09 09:45:18

标签: c# sql-server database

我使用此代码删除checkboxdatagridview选择的记录,但是执行命令的时间太长了

private void delete_Click(object sender, EventArgs e)
    {
        foreach(DataGridViewRow item in advancedDataGridView1.Rows)
        {
            if(bool.Parse(item.Cells[0].Value.ToString()))
            {

                conn.Open();
                SqlCommand cmd = new SqlCommand("delete from tabl where id = '" + item.Cells[1].Value.ToString() + "'", conn);
                cmd.ExecuteNonQuery();
                conn.Close();
            }
        }
        MessageBox.Show("Successfully Deleted....");
    }

并且我将此代码用于复选框

private void Chkselectall_CheckedChanged(object sender, EventArgs e)
    {
        for(int n = 0; n< advancedDataGridView1.Rows.Count;n++)
        {
            advancedDataGridView1.Rows[n].Cells[0].Value = chkselectall.Checked;
        }
    }

我该怎么解决这个问题?

4 个答案:

答案 0 :(得分:6)

那么,您可以按顺序执行一堆命令。对于每个连接,您都需要打开一个新的连接,然后关闭它,并且要保持原样,因此总会涉及开销。最好获得需要删除的ID列表,并将命令更改为

delete from tabl where id in (…)

答案 1 :(得分:2)

全力以赴为您提供帮助,我找到了我需要的东西,我希望它可以帮助其他人需要类似的东西

String sql;
int parameterCounter;
SqlParameter parameter;

private void delete_Click(object sender, EventArgs e)
{
    sql = "delete from tabl where id in (";
    parameterCounter = 0;

    using (SqlConnection cn = new SqlConnection("....")) {
    using (SqlCommand cmd = new SqlCommand(sql, cn)) {
    foreach (DataGridViewRow item in advancedDataGridView1.Rows) {
     if (bool.Parse(item.Cells[0].Value.ToString())) {
        parameterCounter++;
        parameter = new SqlParameter();
        parameter.ParameterName = "@par" + parameterCounter.ToString();
        parameter.DbType = System.Data.DbType.Int32;
        parameter.Value = item.Cells[1].Value;
        cmd.Parameters.Add(parameter);
        sql = sql + $"{parameter.ParameterName},";
        // collecting all ids
     }
  }
  sql = sql.TrimEnd(',');
  sql = sql + ")";

  cmd.CommandText = sql;
  cmd.Connection = cn;
  cn.Open();
  cmd.ExecuteNonQuery();
    MessageBox.Show("Successfully Deleted....");
}

答案 2 :(得分:0)

您做错了几件事。

  • 您正在使用内联查询,我们已经有很多线程在讨论这个问题,因为它为SQLInjection打开了广阔的大门。
  • 降低执行性能的原因是您的处理方式。也就是说,您要遍历每一行,并为每个匹配项打开连接并执行删除查询。

我希望您使用以下步骤:

  • 遍历行并根据条件收集要删除的项目。
  • 构造一个接受字符串类型参数的参数化查询。
  • 将收集的ID分配为参数值。
  • 执行查询。

请在下面找到示例代码:

private void delete_Click(object sender, EventArgs e)
{
    List<string> selectedIds = new List<string>();
    foreach (DataGridViewRow item in advancedDataGridView1.Rows)
    {
        if (bool.Parse(item.Cells[0].Value.ToString()))
        {
            selectedIds.Add("'" + item.Cells[1].Value.ToString() + "'");
            // collecting all ids
        }
    }
    String sql = "delete from tabl where id in(@idsToDelete)";
    using (SqlConnection cn = new SqlConnection("Your connection string here")) 
    {
        cn.Open();
        using (SqlCommand cmd = new SqlCommand(sql, cn)) 
        {
            cmd.Parameters.Add("@idsToDelete", SqlDbType.VarChar).Value = string.Join(",", selectedIds);
            cmd.ExecuteNonQuery();
        }
    }      
}

答案 3 :(得分:-1)

您应该将sql操作移出foreach循环。在循环中连接sql字符串,然后在循环外执行它。

private void delete_Click(object sender, EventArgs e)
    {
        StringBuilder sb = new StringBuilder();
        foreach(DataGridViewRow item in advancedDataGridView1.Rows)
        {
            if(bool.Parse(item.Cells[0].Value.ToString()))
            {
                sb.AppendFormat("delete from tabl where id='{0}';{1}", item.Cells[1].Value, Environment.NewLine);

            }
        }
                conn.Open();
                SqlCommand cmd = new SqlCommand(sb.ToString(), conn);
                cmd.ExecuteNonQuery();
                conn.Close();
        MessageBox.Show("Successfully Deleted....");
    }

理论上,由于SQL注入,直接传递sql参数是非常危险的。您必须自己处理