我有一个SQL Server Compact数据库,我正在尝试使用cmd.ExecuteNonQuery()
将记录插入其中。这种方法在另一个项目中运行得很好,但现在不起作用。
private void AddNewProfile() {
try {
using(SqlCeConnection conn = new SqlCeConnection(Properties.Settings.Default.dbConnectionString)) {
using(SqlCeCommand cmd = new SqlCeCommand()) {
cmd.Connection = conn;
cmd.CommandText = "INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription) VALUES ('@name', '@path', '@desc');";
cmd.Parameters.AddWithValue("@name", SqlDbType.Text).Value = "New Profile";
cmd.Parameters.AddWithValue("@path", SqlDbType.Text).Value = "C:\\";
cmd.Parameters.AddWithValue("@desc", SqlDbType.Text).Value = "A blank profile.";
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
}
catch(Exception ex) {
MessageBox.Show(ex.Message, "Error");
}
}
问题来自参数 - 我几乎从我的其他项目中复制了代码,但它无法正常工作。而不是执行此:
INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription)
VALUES ('New Profile', 'C:\\', 'A blank profile.');
执行此操作:
INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription)
VALUES ('@name', '@path', '@desc');
这里有什么问题?
答案 0 :(得分:5)
两个问题:
首先,由于引号,您的SQL正在指定 literal 值。它应该是:
INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription)
VALUES (@name, @path, @desc)
这样,SQL引用的是参数,而不是值为“@name”,“@ path”和“@desc”的文字。
(我也删除了不必要的分号。)
其次,调用AddWithValue
,但提供类型作为值,然后覆盖该值。这是毫无意义和令人困惑的 - 你指定的类型将会丢失。你应该使用:
cmd.Parameters.Add("@name", SqlDbType.Text).Value = "New Profile";
最后,您无需致电conn.Close()
- 它已经在using
声明中......您可以将conn
传递给SqlCeCommand
构造函数,使事情稍微简单。
答案 1 :(得分:3)
声明参数时,不需要使用单引号。使用单引号,SQL会将它们识别为 string literal 而不是参数。只需在SqlCommand
中使用它们
INSERT INTO Profiles (ProfileName, ProfilePath, ProfileDescription)
VALUES (@name, @path, @desc)
此外,您以错误的方式使用AddWithValue
。它不需要类型。
cmd.Parameters.AddWithValue("@name", "New Profile");
cmd.Parameters.AddWithValue("@path", "C:\\");
cmd.Parameters.AddWithValue("@desc", "A blank profile.");
或者,如果您要声明其类型,则可以使用Add
cmd.Parameters.Add("@name", SqlDbType.Text).Value = "New Profile";
cmd.Parameters.Add("@path", SqlDbType.Text).Value = "C:\\";
cmd.Parameters.Add("@desc", SqlDbType.Text).Value = "A blank profile.");
你的conn.Close();
是多余的。 using
statement将为您处理。在幕后,SqlConnection.Dispose()
调用SqlConnection.Close()
方法。
答案 2 :(得分:1)
问题1:您在单引号中包含参数(@ name,@ path,@ desc),因此您将值传递为@name, @path, @desc
。
解决方案1:使用参数化查询时,不应将参数括在单引号内。
替换它:
cmd.CommandText = "INSERT INTO Profiles (ProfileName, ProfilePath,
ProfileDescription) VALUES ('@name', '@path', '@desc');";
有了这个:
cmd.CommandText = "INSERT INTO Profiles
(ProfileName, ProfilePath, ProfileDescription)
VALUES (@name, @path, @desc);";
问题2:您需要为Parameters.AddWithValue()
方法提供参数名称及其值
解决方案2:
替换它:
cmd.Parameters.AddWithValue("@name", SqlDbType.Text).Value = "New Profile";
cmd.Parameters.AddWithValue("@path", SqlDbType.Text).Value = "C:\\";
cmd.Parameters.AddWithValue("@desc", SqlDbType.Text).Value = "A blank profile.";
有了这个:
cmd.Parameters.AddWithValue("@name","New Profile");
cmd.Parameters.AddWithValue("@path","C:\\");
cmd.Parameters.AddWithValue("@desc","A blank profile.");
完整代码:
private void AddNewProfile() {
try {
using(SqlCeConnection conn = new SqlCeConnection(Properties.Settings.Default.dbConnectionString)) {
using(SqlCeCommand cmd = new SqlCeCommand()) {
cmd.Connection = conn;
cmd.CommandText = "INSERT INTO Profiles (ProfileName, ProfilePath,
ProfileDescription) VALUES (@name,@path, @desc);";
cmd.Parameters.AddWithValue("@name","New Profile");
cmd.Parameters.AddWithValue("@path","C:\\");
cmd.Parameters.AddWithValue("@desc","A blank profile.");
conn.Open();
cmd.ExecuteNonQuery();
}
}
}
catch(Exception ex) {
MessageBox.Show(ex.Message, "Error");
}
}