如果不存在插入其他更新SQL

时间:2019-06-20 08:04:07

标签: c# sql-server

我在做什么错了?

我正在创建一个以数据库为中心的Windows Form C#应用程序。在我的表单应用程序中,我有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 个答案:

答案 0 :(得分:3)

  

我在做什么错了?

您没有执行命令。
完全配置命令后,您的代码应带有cmd.ExecuteNonQuery();

但是,一旦添加,您将从SQL Server收到语法错误消息。 这是因为您缺少Exists运算符的右括号。

请注意,在此代码中,做错事情不是唯一的事情:

  1. 您正在将UI代码与应用程序代码混合在一起。
  2. 您正在使用全局变量(或至少是一个字段)来保存SqlConnection的实例。
  3. 您正在使用可怕的名称作为参数和texbox。
  4. 您正在使用AddWithValue
  5. 您正在使用的“ upsert”模式非常麻烦,并且可能会出现问题。

以下是更好的选择:

第一
您应该阅读有关n-tier architectural pattern的信息。
对于Winforms,通常使用MVP来实现。
一方面,创建一个Customr类来保存数据,然后使用该类在代码中传递客户数据,而不是直接将文本框数据发送到数据库中。

第二
最佳做法是在using语句内使用局部变量,以确保处置SqlConnection实例以及将基础连接返回到连接池。

第三
想象一下,必须像这样在代码中更改某些内容,而不是像这样更改代码:

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

现在,您不必阅读SQL即可弄清楚该参数的含义- 花费在理解代码上的时间和精力越少越好。

第四
链接中的文章详细说明了为什么会出现问题, 但要点是必须从用法中推断出参数的数据类型, 并可能由于错误地推断数据类型而导致错误,甚至更糟的是,错误地将错误数据悄悄输入数据库。

第五
更好的模式是先更新,然后有条件地插入(如Aaron Bertrand's answer here中所示),并在多用户(或多线程)环境中将整个内容包装在事务中。

话虽如此,修改后的代码应该更像这样:

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

答案 1 :(得分:0)

我没有检查SQL语句。

但是您可以在添加后检查代码,因为如果不执行数据库命令,您将看不到更改。

cmd.ExecuteNonQuery();

之前

 con.Close();

答案 2 :(得分:0)

我检查了您的代码,没有什么问题。

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

相关问题