MunsuleMPI Ответов: 2

С этой командой уже связан открытый datareader, который должен быть закрыт первым


Я не знаю, что делать дальше. Пожалуйста, помогите мне

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

using (SqlCommand readCompu = new SqlCommand("select [computer name] from computer", con))
            {
                SqlDataReader readComputers = readCompu.ExecuteReader();
                while (readComputers.Read())
                {
                    
                    commppName = readComputers[0].ToString();
                    if (listAllConnectedComputers.Items.Contains(commppName))
                    {
                        //Update Computer set status='Connected'
                        using (SqlCommand insertToDB = new SqlCommand("update computer set [Computer Status]='Connected' where [computer name]='" + commppName + "' ", con))
                        {
                            insertToDB.ExecuteNonQuery();
                        }
                    }
                    else
                    {
                        //Update Computer set status='Disconnected'
                        using (SqlCommand inseritToDB = new SqlCommand("update computer set [Computer Status]='Disconnected' where [computer name]='" + commppName + "' ", con))
                        {
                            inseritToDB.ExecuteNonQuery();
                        }
                    }
                } readComputers.Close();
            }

F-ES Sitecore

когда вы получаете ошибку, всегда говорите, на какой строке происходит ошибка.

2 Ответов

Рейтинг:
14

Dave Kreskowiak

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

Ответ на этот вопрос довольно прост. Создайте и откройте второе соединение с базой данных для выполнения запросов на обновление.


Maciej Los

Да, это довольно легко решить, но ОП нужно предупредить... смотрите мой ответ.
Кстати: 4!

Рейтинг:
11

Maciej Los

Как отметил в своем ответе Дэйв Кресковяк, ошибка очень специфична и легко решаема...

Но ... я должен предупредить тебя!

1)
Ваш код таков SQL-инъекция[^] уязвимый!
Никогда не использовать объединенная строка в виде текста команды! Воспользуйся параметризованный запрос[^] вместо этого!

Видеть:
Как: защититься от инъекционных атак в ASP.NET[^]
Как выполнить параметризованный запрос[^]

2)
Я бы строго рекомендовал НЕ используйте такое программное обеспечение в своей базе данных, потому что оно убивает производительность базы данных и может стать причиной серьезных проблем. Представьте себе, что у вас есть список из 10 тысяч компьютеров. Ваше программное обеспечение производит 10 тысяч запросов за несколько секунд, которые ищут и изменяют данные в вашей базе данных. Каждый раз, когда выполняется новый запрос, ваше программное обеспечение создает новое соединение. Итак, 10K соединений за несколько секунд - это остается мне атакой на SQL Server, которую вы выполняете по своему желанию. ОМГ! Ваш SQL-сервер перестанет отвечать на запросы или начнет отклонять другое соединение.

Пожалуйста, прочтите это:
Мониторинг безопасности и обнаружение атак[^]
Определение уязвимости системы безопасности[^]
Глава 14-повышение производительности SQL Server[^]- старая документация, но очень полезная в вашем случае.

Есть несколько возможных решений. Один из них:
Обновите базу данных на уровне MS SQL server, например, с помощью одного оператора update:

UPDATE t1
SET t1.[Status]  = t2.[Status]
FROM Computer AS t1 INNER JOIN ConnectedComputers AS t2 ON t1.CompName = t2.CompName


Подробнее на: Как обновить из SELECT в SQL Server? - переполнение стека[^]

Кстати! Это тоже может быть полезно: Визуальное представление SQL-соединений[^]