簡體   English   中英

ExecuteNonQuery()不起作用

[英]ExecuteNonQuery() doesn't work

每當我嘗試運行代碼時,都會出現以下異常:

System.Data.dll中發生了類型為'System.Data.SqlClient.SqlException'的未處理的異常

附加信息:')'附近的語法不正確。

嘗試了多種解決方法,但我從未超越ExectueNonQuery行。 有人可以告訴我這是怎么回事嗎?

private void button1_Click(object sender, EventArgs e)
{
    SqlConnection con = new SqlConnection(@"Data Source=CHARLIE-PC\MSSQLSERVER1;Initial Catalog=Tema;Integrated Security=True;");
    con.Open();

    SqlCommand cmd = new SqlCommand("INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES ('"+idFis.Text+ "','"+ numeFis.Text + "','" +idFoldFis.Text +"',)", con);

    cmd.ExecuteNonQuery();
    con.Close();
}

雖然其他問題都說明了根本問題,即結尾的逗號,但實際上您必須對查詢做得更好。 不要像這樣將查詢粘合在一起,而應使用參數。 如果您不這樣做,那么您將面臨巨大的安全問題 另外,您確實必須將連接放在using語句中,以便當確實發生錯誤時,連接仍將關閉。

private void button1_Click(object sender, EventArgs e)
{
    using(SqlConnection con = new SqlConnection(@"Data Source=CHARLIE-PC\MSSQLSERVER1;Initial Catalog=Tema;Integrated Security=True;"))
    {
        con.Open();
        SqlCommand cmd = new SqlCommand("INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES (@idFis,@numeFis,@idFoldFis)",con);
        cmd.Parameters.Add("@idFis", SqlDbType.NVarChar, -1).Value = idFis.Text;
        cmd.Parameters.Add("@numeFis", SqlDbType.NVarChar, -1).Value = numeFis.Text;
        cmd.Parameters.Add("@idFoldFis", SqlDbType.NVarChar, -1).Value = idFoldFis.Text;
        cmd.ExecuteNonQuery();
    }
}

逗號是您的問題,但至少在繼續之前,我建議您進行一些其他更改:

  1. 不要將連接字符串嵌入每個數據庫連接請求中。 使用app.config / web.config或其他任何東西:)
  2. 確保正確處理了連接
  3. 參數化任何SQL查詢以防止注入攻擊
  4. 將數據庫命令抽象到單獨的業務層

1.使用“ app.config”作為連接字符串

關於保持連接字符串安全的文檔很多,但是至少不要將它們直接嵌入每個連接代碼中。

在您的客戶端項目中添加“ app.config”(或利用Web項目的web.config)。 至少,這看起來像這樣:

<configuration>
  <appSettings>
      <add key="db" value="Data Source=CHARLIE-PC\MSSQLSERVER1;Initial Catalog=Tema;Integrated Security=True;" />
  </appSettings>
</configuration>

然后在項目中添加對“ System.Configuration”的引用,然后可以在代碼中像這樣引用它:

var con = new SqlConnection(ConfigurationManager.AppSettings["db"]);

2.確保正確處理了連接命令

裹在連接和命令using 這是一個例子:

using (var con = new SqlConnection(ConfigurationManager.AppSettings["db"]))
{
    con.Open();
    var sql = "/* My command here */";
    using (var cmd = new SqlCommand(sql, con))
    {
        // SQL execution here
    }
} // Closing is now handled for you (even if errors occur)

3.參數化任何SQL查詢以防止注入攻擊

串聯字符串對於SQL命令是非常危險的(只是google“ SQL Injection”)。 這是保護自己的方法。

using (var con = new SqlConnection(ConfigurationManager.AppSettings["db"]))
{
    con.Open();
    var sql = "INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES (@idFisier, @nume, @idFolder)";
    using (var cmd = new SqlCommand(sql, con))
    {
        cmd.Parameters.Add("@idFisier", SqlDbType.VarChar).Value = idFis.Text;
        cmd.Parameters.Add("@nume", SqlDbType.VarChar).Value = numeFis.Text;
        cmd.Parameters.Add("@idFolder", SqlDbType.VarChar).Value = idFoldFis.Text;
        cmd.ExecuteNonQuery();
    }
} // Closing is now handled for you (even if errors occur)

4.將數據庫命令抽象到單獨的業務層

通常,這是最佳實踐,並且通過將單獨的類(甚至是類庫)編寫為僅包含數據命令的業務層,可以避免許多麻煩。 然后,您的UI將僅處理調用業務層方法。

如果您的數據庫發生了變化,或者您需要在UI的其他部分中執行類似的功能,那么在整個UI中更新同一查詢並不是一件很有趣的事情,而不是僅更新業務層中的單個位置。

使SQL 易於閱讀參數化 ,您會發現該例程易於實現:

// Extract a method (or even a class): do not mix UI and business logic/storage
// Just RDBMS logic: no UI controls or something at all
private static void CoreInsertFisier(string idFisier, nume, idFolder) {
  // Do not hardcode the connection string, but read it (from settings)
  // wrap IDisposable into using
  using (SqlConnection con = new SqlConnection(ConnectionStringHere)) {
    con.Open();

    // Make sql readable (use verbatim strings @"...")
    // Make sql parameterized 
    string sql = 
      @"INSERT INTO Fisier (
           idFisier, 
           Nume, 
           idFolder)
        VALUES (
           @prm_idFisier, 
           @prm_Nume, 
           @prm_idFolder)";

     // wrap IDisposable into using
     using (SqlCommand cmd = new SqlCommand(sql, con)) {
       // Parameters.Add(...) is a better choice, but you have to know fields' types
       cmd.Parameters.AddWithValue("@prm_idFisier", idFisier); 
       cmd.Parameters.AddWithValue("@prm_Nume", nume);
       cmd.Parameters.AddWithValue("@prm_idFolder", idFolder); 

       cmd.ExecuteNonQuery(); 
     }
  }
}
...

private void button1_Click(object sender, EventArgs e) {
  // UI: just one call - please insert these three textbox into db
  CoreInsertFisier(idFis.Text, numeFis.Text, idFoldFis.Text);
}

您還有一個多余的逗號:

private void button1_Click(object sender, EventArgs e)
    {
        SqlConnection con = new SqlConnection(@"Data Source=CHARLIE-PC\MSSQLSERVER1;Initial Catalog=Tema;Integrated Security=True;");
        con.Open();
        SqlCommand cmd = new SqlCommand("INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES ('"+idFis.Text+ "','"+ numeFis.Text + "','" +idFoldFis.Text +"')",con);
        cmd.ExecuteNonQuery();
        con.Close();
    }

無論如何,正如其他人所說,以這種方式連接您的查詢是一個非常糟糕的主意,因為它可能導致您在代碼上進行sql注入。

嘗試刪除,在結束之前)

   SqlCommand cmd = new SqlCommand("INSERT INTO Fisier (idFisier, Nume, idFolder) VALUES ('"+idFis.Text+ "','"+ numeFis.Text + "','" +idFoldFis.Text +"')",con);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM