ЕСЛИ НЕ СУЩЕСТВУЕТ, ВСТАВЬТЕ В Иное ОБНОВЛЕНИЕ SQL - PullRequest
0 голосов
/ 20 июня 2019

Что я делаю не так?

Я работаю над созданием приложения C # для Windows Forms с центром в базе данных. В моем приложении для форм есть 4 текстовых поля, которые вставляют данные в одну простую таблицу базы данных.

Если я что-то наберу в textBox1 (Customer_Name) и нажму кнопку «Проверить и сохранить», мне бы хотелось, чтобы действие проверило, существует ли Customer_Name.

Если он не существует, он должен вставить данные в базу данных.

Если он существует, он должен обновить мою базу данных информацией, введенной в textBox1-4

У меня есть этот код:

private void Button1_Click(object sender, EventArgs e)
{
    con.Open();

    SqlCommand cmd = new SqlCommand("IF NOT EXISTS (SELECT * FROM [Customers] WHERE Customer_Name=@aa BEGIN INSERT INTO [Customers](Customer_Name,Cellphone_Number,Telephone_Number,Alternative_Number) VALUES(@aa,@bb,@cc,@dd) END ELSE BEGIN UPDATE [Customers] SET Customer_Name=@aa, Cellphone_Number=@bb, Telephone_Number=@cc, Alternative_Number=@dd END", con);

    cmd.Parameters.AddWithValue("@aa", textBox1.Text);   
    cmd.Parameters.AddWithValue("@bb", textBox2.Text);  
    cmd.Parameters.AddWithValue("@cc", textBox3.Text);  
    cmd.Parameters.AddWithValue("@dd", textBox4.Text);

    con.Close();
}

Никакая информация не вводится в базу данных при нажатии кнопки не обновляет информацию.

Ответы [ 3 ]

3 голосов
/ 20 июня 2019

Что я делаю не так?

Вы не выполняете команду.
Ваш код должен иметь cmd.ExecuteNonQuery(); после полной настройки команды.

Однако, как только вы добавите это, вы получите сообщение об ошибке синтаксиса от SQL Server. Это потому, что вам не хватает закрывающей скобки для оператора Exists.

Обратите внимание, что это далеко не единственное, что вы делаете неправильно в этом коде:

  1. вы смешиваете код пользовательского интерфейса с кодом приложения.
  2. вы используете глобальную переменную (или, как минимум, поле) для хранения вашего экземпляра SqlConnection.
  3. вы используете ужасные имена для ваших параметров и текстовых полей.
  4. Вы используете AddWithValue.
  5. шаблон для "upsert", который вы используете, громоздок и потенциально проблематичен.

Вот лучшие альтернативы:

Первый
Вам следует прочитать о n-уровневом архитектурном шаблоне .
Для winforms это обычно реализуется с использованием MVP .
Во-первых, вместо отправки данных текстовых полей непосредственно в базу данных, создайте класс Customr для хранения данных и используйте его для передачи данных клиента в вашем коде.

Второй
Рекомендуется использовать локальную переменную внутри оператора using для обеспечения удаления экземпляра SqlConnection и возврата базового соединения в пул соединений.

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

cmd.Parameters.Add(@"CustomerName", SqlDbType.NVarChar).Value = customerName;

Теперь вам не нужно читать SQL, чтобы понять, что означает этот параметр - чем меньше времени и усилий вы потратите на понимание кода, тем лучше.

Четвертый
Статья в ссылке объясняет, почему это проблематично, но главное в том, что тип данных параметра должен быть выведен из использования, и это может привести к ошибкам из-за неверно выведенного типа данных или, что еще хуже, неверно введенных в базу данных данных.

Пятый
Лучше всего сначала обновить, а затем вставить условно - как показано в ответе Аарона Бертранда - и в многопользовательской (или многопоточной) среде обернуть все в транзакции.

При всем этом, пересмотренный код должен выглядеть примерно так:

private void AddOrUpdateCustomer(Customer customer)
{
    // Data validity tests omitted for brevity - but you should ensure 
    // customer has all it's properties set correctly.

    // Readable, properly indented code - Isn't that much easier to debug?
    var sql = @"
        SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
        BEGIN TRANSACTION;
        UPDATE [Customers] 
        SET 
        Cellphone_Number = @Cell, 
        Telephone_Number = @Telephone, 
        Alternative_Number = @Alternative
        WHERE Customer_Name = @Name 

        IF @@ROWCOUNT = 0
        BEGIN 

        INSERT INTO [Customers](Customer_Name, Cellphone_Number, Telephone_Number, Alternative_Number) 
        VALUES(@Name, @Cell, @Telephone, @Alternative) 

        END
        COMMIT TRANSACTION;"; 


    // connectionString should be obtained from configuration file
    using(var con = new SqlConnection(connectionString))
    {
        using(var cmd = new SqlCommand(sql, con))
        {
            cmd.Parameters.Add(@"Name", SqlDbType.NVarChar).Value = customer.Name;
            cmd.Parameters.Add(@"Cell", SqlDbType.NVarChar).Value = customer.Cellphone;
            cmd.Parameters.Add(@"Telephone", SqlDbType.NVarChar).Value = customer.Telephone;
            cmd.Parameters.Add(@"Alternative", SqlDbType.NVarChar).Value = customer.AlternativeNumber;

            con.Open();
            cmd.ExecuteNonQuery();
        }
    }
}
0 голосов
/ 20 июня 2019

Я проверил ваш код, есть несколько проблем.

private void button1_Click(object sender, EventArgs e)
        {
            SqlConnection con = new SqlConnection("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
            con.Open();

            SqlCommand cmd = new SqlCommand("IF NOT EXISTS (SELECT * FROM [Customers] WHERE Customer_Name=@aa BEGIN INSERT INTO [Customers](Customer_Name,Cellphone_Number,Telephone_Number,Alternative_Number) VALUES(@aa,@bb,@cc,@dd) END ELSE BEGIN UPDATE [Customers] SET Customer_Name=@aa, Cellphone_Number=@bb, Telephone_Number=@cc, Alternative_Number=@dd END", con);

            cmd.Parameters.AddWithValue("@aa", textBox1.Text);
            cmd.Parameters.AddWithValue("@bb", textBox2.Text);
            cmd.Parameters.AddWithValue("@cc", textBox3.Text);
            cmd.Parameters.AddWithValue("@dd", textBox4.Text);

            cmd.ExecuteNonQuery();

            con.Close();
        }

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

IF NOT EXISTS (SELECT * FROM [Customers] WHERE Customer_Name=@aa) BEGIN INSERT INTO [Customers](Customer_Name,Cellphone_Number,Telephone_Number,Alternative_Number) VALUES(@aa,@bb,@cc,@dd) END ELSE BEGIN UPDATE [Customers] SET Customer_Name=@aa, Cellphone_Number=@bb, Telephone_Number=@cc, Alternative_Number=@dd WHERE Customer_Name=@aa END

Вставить данные insert data

Обновить данные update data

0 голосов
/ 20 июня 2019

Я не проверял оператор SQL.

Но можете ли вы проверить код после добавления, потому что без выполнения команды База данных вы не увидите изменений.

cmd.ExecuteNonQuery();

до

 con.Close();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...