Не работают параметры, что тут не так

Вставка сообщения не работает! Я пытаюсь вставить данные, используя параметры

System.Data.SqlClient.SqlException: «Имя переменной @name» уже объявлено. Имена переменных должны быть уникальными в пакете запросов или хранимой процедуре».

    SqlCommand com = new SqlCommand();


    
    public Form1()
    {
        InitializeComponent();
    }

    //save | event Click
    private void btnSave_Click(object sender, EventArgs e)
    {



        if (txtName.Text == "" || txtLocation.Text == "")
        {
               MessageBox.Show("no data!","Hey you...",MessageBoxButtons.OK,MessageBoxIcon.Error);
        }

        else

        {
            com.Connection = con;
            com.CommandText = "insert into Table_1 values ( @name ,@location )";
            com.Parameters.AddWithValue("@name", txtName.Text);
            com.Parameters.AddWithValue("@location", txtLocation.Text);
            con.Open();
            com.ExecuteNonQuery();
            con.Close();
        }
        

    }

    //clear fun
    private void Clear()

    {
        txtName.Clear();
        txtLocation.Clear();
    }

    }
}

}

Пожалуйста, объясните, почему вы думаете, что «параметры не работают».

Dour High Arch 18.12.2020 18:57

Пожалуйста, прочтите Как задать вопрос и следуйте приведенным там советам о том, что делает вопрос хорошим.

Heretic Monkey 18.12.2020 19:00
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
2
2
165
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

У вас проблема с масштабом. Вы определяете SqlCommand com вне области, в которой вы его изменяете (т.е. добавляете в список параметров). По сути, вы добавляете параметр @name каждый раз, когда вызывается ваш метод btnSave_Click.

Переместите строку, в которой вы создаете com, в метод, чтобы она выглядела так:

 SqlCommand com = new SqlCommand();
 com.Connection = con;
 com.CommandText = "insert into Table_1 values ( @name ,@location )";
 com.Parameters.AddWithValue("@name", txtName.Text);
 com.Parameters.AddWithValue("@location", txtLocation.Text);
 con.Open();
 com.ExecuteNonQuery();
 con.Close();

И удалите SqlCommand com = new SqlCommand(); из верхней части кода.

Таким образом, команда создается заново каждый раз, когда запускается метод, и когда она создается заново, список параметров будет пустым, а строки, в которых вы добавляете параметры, не завершатся ошибкой.

РЕДАКТИРОВАТЬ Чтобы уточнить: проблема в том, что когда вы определяете это там, где вы это делаете, вам нужно добавлять параметры только один раз. Как «глобальная переменная» (на самом деле, в вашем коде она называется полем), такая как вы создаете, она создается только один раз, и это нормально. Проблема возникает, когда вы добавляете параметры в SqlCommand. Поскольку этот обработчик нажатия кнопки запускается каждый раз (я предполагаю), что нажимается кнопка, вы постоянно добавляете параметры в список. Первый раз, когда вы нажимаете кнопку, все в порядке, потому что в это время список параметров пуст. В следующий раз, когда вы нажмете кнопку, вы получите исключение, потому что в этот список уже добавлены эти параметры.

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

 com.Connection = con;
 com.CommandText = "insert into Table_1 values ( @name ,@location )";
 com.Parameters.clear();
 com.Parameters.AddWithValue("@name", txtName.Text);
 com.Parameters.AddWithValue("@location", txtLocation.Text);
 con.Open();
 com.ExecuteNonQuery();
 con.Close();

SqlConnection должен использоваться в блоке использования или удаляться в конце метода.

Oscar 18.12.2020 19:10

@Оскар, хотя это хорошая (лучшая) практика, это не обязательно.

squillman 18.12.2020 19:19

Спасибо @squillman, не могли бы вы дать мне больше объяснений. Я добавил SqlCommand com = new SqlCommand(); как глобальную переменную, поэтому я могу получить к ней доступ из любого места. так в чем тут проблема

Mohamed 18.12.2020 19:20

@squillman важно ли добавить con.open(); в 1-й строке прицела или можно поставить где угодно внутри прицела, важна сортировка?

Mohamed 18.12.2020 19:31

@Mohamed Смотрите мое редактирование. А по поводу открытия и закрытия соединения это вообще отдельная тема. Я не могу сказать, что тебе здесь лучше всего делать. Это зависит от множества других вещей, таких как сеть и то, как у вас структурированы другие части вашего кода.

squillman 18.12.2020 19:35

@squillman Утилизация объектов — это больше, чем лучшая практика, поскольку невыполнение этого требования приведет к утечке памяти в вашем приложении.

Oscar 18.12.2020 19:36

@Oscar В общем, никаких реальных аргументов, но здесь это управляемый код, поэтому сборщик мусора его подберет. Это определенно лучшая практика в целом и требуется в определенных обстоятельствах, но с SqlConnection бывают случаи, когда вы намеренно повторно используете экземпляр, и в этом случае вы не хотите оборачивать его в using{} и вы избавляетесь от него в другом месте. Это хорошая привычка, но вы должны знать, когда ее использовать, а когда нет.

squillman 18.12.2020 19:41

@squillman Нет, GC не может собирать неуправляемые объекты, созданные управляемыми классами, поэтому вы обязаны вызывать Dispose(). Если бы это было так просто, то не было бы смысла просить программистов вызывать Dispose(), так как сборщик мусора в конце концов очистил бы его сам. Что касается повторного использования соединений, я лично считаю это запахом кода и, вероятно, нарушением принципа единой ответственности.

Oscar 18.12.2020 19:46

@Оскар Это была моя точка зрения. SqlConnection — это управляемый код. Ваша точка зрения определенно резонирует с чем-то вроде COM-объекта. И тот факт, что SqlConnection МОЖЕТ содержать экземпляр чего-то, что не является управляемым кодом за кулисами, делает using лучшей практикой, потому что вы правы - в этом случае соединение не будет установлено сборщиком мусора, и вы есть утечка памяти. Я не согласен с вами в том, что повторное использование соединений может быть запахом кода. Итак, хотя using и является лучшей практикой, это не обязательно, и я добавлю: «Если вы знаете, что делаете!»

squillman 18.12.2020 19:52

Вместо того, чтобы объявлять Connection как переменную класса, сделайте ее локальной переменной внутри обработчика кликов и поместите ее в блок using. В настоящее время вы добавляете один и тот же параметр при каждом нажатии кнопки.

using(var conn = new SqlConnection()){
   //your code here
}

Другие вопросы по теме