ExecuteNonQuery внутри цикла

Я пытаюсь вставить запись базы данных в цикл на С#.

Это работает, когда я жестко кодирую значения следующим образом:

    string query3 = "INSERT INTO furniture (room_id,member_id) VALUES (222,333);";
    SqlCommand cmd3 = new SqlCommand(query3, sqlConnection3);
    sqlConnection3.Open();

    for (int i = 0; i < arrItemsPlanner.Length; i++)
    {
        try
            {
                cmd3.ExecuteNonQuery();
            }
            catch
            {
                return "Error: Item could not be saved";
            }
            finally
            {
                //Fail
            }
        }

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

    string query3 = "INSERT INTO furniture (room_id,member_id) VALUES (@room_id,333);";
    SqlCommand cmd3 = new SqlCommand(query3, sqlConnection3);
    sqlConnection3.Open();

    for (int i = 0; i < arrItemsPlanner.Length; i++)
    {
        try
            {
                cmd3.Parameters.Add("@room_id", System.Data.SqlDbType.Int);
                cmd3.Parameters["@room_id"].Value = 222;
                cmd3.ExecuteNonQuery();
            }
            catch
            {
                return "Error: Item could not be saved";
            }
            finally
            {
                //Fail
            }
        }

Может ли кто-нибудь увидеть, где я ошибаюсь?

Большое спасибо!


person Dan    schedule 05.01.2012    source источник


Ответы (7)


Похоже, вы снова и снова добавляете в набор параметров команды. Очищайте его с каждой итерацией.

Я бы также предложил создать фактическое исключение, чтобы вы могли увидеть, в чем проблема.

person Tim Medora    schedule 05.01.2012
comment
Спасибо - я ломал голову над этим целую вечность! Вам, ребята, нужно несколько секунд, чтобы понять. Большое спасибо всем. - person Dan; 05.01.2012
comment
@Дэн - нет проблем! Кстати, я бы предложил обновить ваш код, чтобы использовать правильное расположение с оператором using (как это было предложено постом Остина Салонена). - person Tim Medora; 06.01.2012

Проверенное и простое решение. Если вы используете параметры в цикле, вам необходимо очистить параметры после выполнения запроса. Таким образом, вы можете использовать это

cmd3.executeNonQuery();
cmd3.Parameters.Clear();
person Vaibhav Jain    schedule 01.01.2014

Это не проверено, но должно работать как альтернатива. Просто добавьте его один раз и постоянно обновляйте его значение.

....
cmd3.Parameters.Add("@room_id", System.Data.SqlDbType.Int);

for (int i = 0; i < arrItemsPlanner.Length; i++)
{
    try
        {
            cmd3.Parameters["@room_id"].Value = 222;
            cmd3.ExecuteNonQuery();
        }
....

Кроме того, ваш SqlCommand должен находиться в пределах блока using, как и ваш SqlConnection. Полный код не показан, поэтому я не знаю, действительно ли ваше соединение выполняется таким образом.

using (var conn = new SqlConnection(...))
using (var cmd = new SqlCommand(..., conn))
{

}
person Austin Salonen    schedule 05.01.2012

То, что вы делаете, это добавление параметра когда-либо итерации цикла. В приведенном ниже коде он добавляет параметр один раз и просто изменяет значение одного параметра. Попробуй это:

string query3 = "INSERT INTO furniture (room_id,member_id) VALUES (@room_id,333);"; 
SqlCommand cmd3 = new SqlCommand(query3, sqlConnection3);
cmd3.Parameters.Add("@room_id", SqlDbType.Int);

sqlConnection3.Open(); 

for (int i = 0; i < arrItemsPlanner.Length; i++) 
{ 
    try 
        { 
            cmd3.Parameters["@room_id"].Value = 222; 
            cmd3.ExecuteNonQuery(); 
        } 
        catch 
        { 
            return "Error: Item could not be saved"; 
        } 
        finally 
        { 
            //Fail 
        } 
    } 
person Community    schedule 05.01.2012

Да, не добавляйте параметр в цикл, только установите его значение:

string query3 = "INSERT INTO furniture (room_id,member_id) VALUES (@room_id,333);";
SqlCommand cmd3 = new SqlCommand(query3, sqlConnection3);
sqlConnection3.Open();

cmd3.Parameters.Add("@room_id", System.Data.SqlDbType.Int);

for (int i = 0; i < arrItemsPlanner.Length; i++)
{
    try
        {
            cmd3.Parameters["@room_id"].Value = 222;
            cmd3.ExecuteNonQuery();
        }
        catch
        {
            return "Error: Item could not be saved";
        }
        finally
        {
            //Fail
        }
    }
person competent_tech    schedule 05.01.2012

cmd3.Parameters.Add("room_id", System.Data.SqlDbType.Int);

// также не продолжайте добавлять его в цикл

cmd3.Parameters["room_id"].Value = 222; 

Нет @needed в коллекции параметров при использовании сервера sql

person Tony Hopkinson    schedule 05.01.2012

Еще одно решение для тех, кто просматривает эту ветку. Создайте два соединения. Один для вашего цикла, а другой для отправки ваших операторов NonQuery. Это сработало для меня.

person eDriven_Levar    schedule 24.10.2016