el_tot93 Ответов: 2

Кнопка Удалить работает слишком медленно в чем проблема


я использую этот код для удаления записей, которые выбраны флажком в datagridview, но это займет слишком много времени, чтобы выполнить команду

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;
            }
        }


Что я уже пробовал:

что я должен сделать, чтобы решить эту проблему


новое обновление

sql = "delete from tabl where id in (";
           parameterCounter = 0;
           using (SqlConnection cn = new SqlConnection("Data Source=SQL5035.site4now.net;Initial Catalog=DB_A448D1_ilgswork;User Id=**********;Password=**********"))

           {
               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();
               }

Maciej Los

Похоже, вы не хотите слушать наши советы по поводу SQL-инъекций...
Основываясь на этом фрагменте кода, никто не может сказать причину медленного выполнения кода.

el_tot93

моя проблема в том, что я новичок в кодировании

Karthik_Mahalingam

является ли идентификатор целым числом ?

el_tot93

да

Karthik_Mahalingam

это решено?

el_tot93

вы хотите помочь или хотите получить ответ

Karthik_Mahalingam

если ошибка все еще сохраняется, Я помогу Вам ее исправить.

el_tot93

блокировка моего обновления

el_tot93

это и есть способ писать

Karthik_Mahalingam

да

2 Ответов

Рейтинг:
20

RickZeeland

Вместо отправки большого количества команд вы можете попробовать отправить одну команду с помощью предложения "IN", см. пример здесь: Оператор SQL IN[^]


Maciej Los

Хорошая идея!
Но боюсь, что это не поможет. Дело в том, что OP хочет использовать команды, которые могут вызвать sql-инъекцию.

Dave Kreskowiak

Его проблема с производительностью заключается в том, что он, похоже, использует поле ID, которое является строкой, и я готов поспорить, что это поле не индексируется.

RickZeeland

Это кажется очень вероятным, но на данный момент метод IN, кажется, работает для него ...

0x01AA

Насколько я знаю, можно динамически создать предложение IN и впоследствии установить параметр. Что-то Ликс SELECT * FROM Tbl WHERE Name IN (@p0, @p1, @p2, @p3,....) При этом о SQL-инъекции не может быть и речи

Рейтинг:
2

sachin.vishwa90

Знаете ли вы, почему это происходит медленно, из-за количества вызовов базы данных, больше количества проверенных элементов, больше количества вызовов базы данных.
Что вы можете сделать, чтобы этого избежать
1) Создайте хранимую процедуру в вашей базе данных, которая принимает список элементов, подлежащих удалению (Как Передать Массив Или Список В Хранимую Процедуру[^])
2) вызовите хранимую процедуру с помощью команды (так как вы хотите использовать эту команду)
3) в течение одного вызова БД вы сможете удалить N номеров записей.
что касается вашего комментария о том, что вы новичок в кодировании, то такого рода проблемы должны мотивировать вас писать хороший код, и это включает в себя обучение, которое поможет вам улучшить свои навыки кодирования.

Вызов хранимой процедуры

using (SqlConnection conn = new SqlConnection("yourconnectionstring")) {
    conn.Open();

    // 1.  create a command object identifying the stored procedure
    SqlCommand cmd  = new SqlCommand("yourprocedure", conn);

    // 2. set the command object so it knows to execute a stored procedure
    cmd.CommandType = CommandType.StoredProcedure;

    // 3. add parameter to command, which will be passed to the stored procedure
    cmd.Parameters.Add(new SqlParameter("yourparameter", list));
    
    // execute the command
    cmd.ExecuteNonQuery();
    
    
}


Счастливого обучения.


el_tot93

о том что я новичок и не знаю как работать с хранимой процедурой я еще не знал