SqlCommand.ExecuteNonQuery()不更新我的数据库

时间:2011-12-21 12:24:37

标签: c# sql

我正在设计一个数据库应用程序,并且有一个填充来自数据库的数据的表单。如果用户双击表单上的任何文本框,他们可以使用输入框更改该值,然后输入框执行以下代码以更新数据库。

 private void ProcessChanges(string strField, string strCurrentValue)
    {
        //...Connect To Database...//

        string strCaseNo = txtCaseNo.Text;
        string strConnect = BuildConnectionString();
        SqlConnection linkToDB = new SqlConnection(strConnect);
        linkToDB.Open();

        //...Request User Input New Value...//

        string strMessage = "Enter ammended details and click OK," + Environment.NewLine +
                                "or click Cancel to exit.";
        string strInput = Interaction.InputBox(strMessage, "Case Details", strCurrentValue);

        //...Send User Input to Database...//

        string commandText = "UPDATE tblCases SET @FieldVal = @InputVal WHERE CaseNo = @CaseNoVal;";
        SqlCommand sqlCom = new SqlCommand(commandText, linkToDB);
        sqlCom.Parameters.Add("@FieldVal", SqlDbType.Text);
        sqlCom.Parameters.Add("@InputVal", SqlDbType.Text);
        sqlCom.Parameters.Add("@CaseNoVal", SqlDbType.VarChar);
        sqlCom.Parameters["@FieldVal"].Value = strField;
        sqlCom.Parameters["@InputVal"].Value = strInput;
        sqlCom.Parameters["@CaseNoVal"].Value = strCaseNo;
        int intQuery = sqlCom.ExecuteNonQuery();
        MessageBox.Show(intQuery.ToString());
    }

问题是数据库根本没有更新。我知道连接正常,因为在我的应用程序中使用了相同的ConnectionStringBuilder。我还在最后添加了消息框,它告诉我ExecuteNonQuery()的返回值是'1',这表明行已经更新。然而,我的数据库没有任何变化,现在它真的很烦我。

3 个答案:

答案 0 :(得分:7)

您不能将变量用于列名称。您必须构造您的sql字符串,列名称嵌入到字符串中。

string commandText = 
  "UPDATE tblCases SET [" + strField + "] = @InputVal WHERE CaseNo = @CaseNoVal;"

但是你必须检查strField的sql注入攻击的值。

答案 1 :(得分:1)

如果您更新CommandText行,如下所示:

string commandText = "UPDATE tblCases SET @FieldVal = " + strField +  " WHERE CaseNo = @CaseNoVal;";

并删除行

sqlCom.Parameters.Add("@FieldVal", SqlDbType.Text);
sqlCom.Parameters["@FieldVal"].Value = strField;

请注意,通过执行此操作,您可能会对sql注入攻击开放,因此您需要真正信任提供给此方法的值,或者做一些工作以确保strField的任何值都不包含实际的SQL语句。

e.g。如果strField包含;[some malicious SQL here],那么这将使用分配给该连接的用户的权限运行。

答案 2 :(得分:0)

@Jan有它。但是,除此之外,真的应该从MSDN处理或关闭SqlConnection

  

如果SqlConnection超出范围,则不会关闭。因此,您必须通过调用Close或Dispose显式关闭连接。关闭和处置在功能上是等效的。如果连接池值Pooling设置为true或yes,则将基础连接返回到连接池。另一方面,如果Pooling设置为false或no,则实际上将关闭与服务器的基础连接。

{C}中存在using构造只是为了这样的事情:

using (SqlConnection linkToDB = new SqlConnection(strConnect)
{
  // use the linkToDb here
}