SqlCommand.ExecuteNonQuery () НЕ обновляет мою базу данных - PullRequest
2 голосов
/ 21 декабря 2011

Я разрабатываю приложение базы данных, и у меня есть форма, которая заполняется данными из базы данных . Если пользователь дважды щелкает любое из текстовых полей в форме, он может изменить значение, используя поле ввода, которое затем выполняет следующий код для обновления базы данных.

 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 ]

7 голосов
/ 21 декабря 2011

Нельзя использовать переменные для имен столбцов.Вы должны сконструировать строку sql так, чтобы имена столбцов были встроены в строку.

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

Но вы должны проверить значение strField для атак с внедрением sql.

1 голос
/ 21 декабря 2011

Если вы обновите строку 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 заявления.

например. если strField содержит ;[some malicious SQL here], то это будет выполняться с разрешениями пользователя, назначенного для подключения.

0 голосов
/ 21 декабря 2011

@ У Яна это есть. Но, кроме того, вы действительно должны избавиться или закрыть свой SqlConnection от MSDN:

Если SqlConnection выходит из области видимости, он не будет закрыт. Поэтому вы должны явно закрыть соединение, вызвав Close или Dispose. Close и Dispose функционально эквивалентны. Если для значения пула соединений Pooling установлено значение true или да, базовое соединение возвращается обратно в пул соединений. С другой стороны, если для пула задано значение false или нет, базовое соединение с сервером фактически закрыто.

Конструкция using присутствует в C # именно для такой вещи:

using (SqlConnection linkToDB = new SqlConnection(strConnect)
{
  // use the linkToDb here
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...