2014-02-25 96 views
0

我有一個SQL Server Compact數據庫,我試圖用cmd.ExecuteNonQuery()向它插入一條記錄。此方法在另一個項目中工作得很好,但現在不起作用。SqlCeCommand參數不起作用

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'); 

這裏有什麼問題嗎?

回答

5

兩個問題:

首先,你的SQL被指定,因爲引號文字值。它應該是:

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聲明...你可以通過connSqlCeCommand構造,使事情變得稍微簡單。

+0

這是真的嗎?我覺得自己像個白癡。謝謝你的偉大答案! – Abluescarab

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"); 
    } 
} 
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()方法。