我在做什么错了?
我正在创建一个以数据库为中心的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();
}
单击按钮时没有信息输入数据库,则不会更新任何信息。
答案 0 :(得分:3)
我在做什么错了?
您没有执行命令。
完全配置命令后,您的代码应带有cmd.ExecuteNonQuery();
。
但是,一旦添加,您将从SQL Server收到语法错误消息。
这是因为您缺少Exists
运算符的右括号。
请注意,在此代码中,做错事情不是唯一的事情:
SqlConnection
的实例。AddWithValue
。 以下是更好的选择:
第一
您应该阅读有关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