[英]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
括号。
请注意,在此代码中唯一要做的并不是错误:
SqlConnection
实例。 AddWithValue
。 这里是更好的选择:
第一
您应该阅读有关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.