繁体   English   中英

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

[英]IF NOT EXISTS INSERT INTO ELSE UPDATE SQL

我究竟做错了什么?

我正在创建一个以数据库为中心的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();
}

单击按钮时没有信息输入数据库,则不会更新任何信息。

我究竟做错了什么?

您不执行命令。
您的代码应具有cmd.ExecuteNonQuery(); 一旦命令已完全配置。

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

请注意,在此代码中唯一要做的并不是错误:

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

这里是更好的选择:

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

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

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

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

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

第四
链接中的文章详细说明了为什么会出现问题,但主要要点是必须根据使用情况推断出参数的数据类型,并且由于错误地推断出数据类型(甚至是更糟的情况)而导致的错误可能会产生错误,而无提示地输入了错误的数据进入数据库。

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

综上所述,修改后的代码应该更像这样:

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

我没有检查SQL语句。

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

cmd.ExecuteNonQuery();

之前

 con.Close();

我检查了您的代码,几乎没有问题。

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

插入资料 插入资料

更新资料 更新数据

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM