SqlCeCommand参数不起作用

时间:2014-02-25 08:59:06

标签: c# sql sql-server-ce

我有一个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');

这里有什么问题?

3 个答案:

答案 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");
    }
}