ExecuteNonQuery()不起作用

时间:2017-01-16 20:52:46

标签: c# sql-server

每次我尝试运行我的代码时,都会遇到以下异常:

  

类型' System.Data.SqlClient.SqlException'未处理的异常   发生在System.Data.dll

中      

其他信息:')'附近的语法不正确。

尝试了多种解决方法,但我从未超越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();
}

5 个答案:

答案 0 :(得分:4)

虽然其他问题说明了根问题,但是你的尾随逗号,你真的必须对你的查询做得更好。不要像这样将查询粘在一起,而是使用参数。 If you do not you are opening yourself to huge security problems。此外,您必须将连接放在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 :(得分:4)

逗号是你的问题,但至少在继续之前我会推荐一些其他更改:

  1. 不要将连接字符串嵌入到每个数据库连接请求中。使用app.config / web.config或其他任何东西:)
  2. 确保您的连接是正确处理的命令
  3. 参数化任何SQL查询以防止注入攻击
  4. 将数据库命令抽象到单独的业务层
  5. <强> 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命令非常危险(只是谷歌“SQL注入”)。这是如何保护自己。

    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中更新相同的查询并不是非常有趣,而只是更新业务层中的单个位置。

答案 2 :(得分:3)

使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);
}

答案 3 :(得分:0)

你有一个额外的尾随逗号:

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注入。

答案 4 :(得分:-1)

尝试在结束前删除

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