2015-09-01 1 views
1

Я поддерживаю службу Windows, недавно обновленную/скомпилированную в .Net 4.5, размещенную на сервере 2012 года, и используя ту же базу данных SQL Server 2008, перед обновлением. Мы столкнулись с проблемой, когда он обновляет базу данных, используя простой оператор SQL, который, по-видимому, всегда работал до обновления. Теперь обновление почти всегда работает, но один раз (возможно?) Тысяча обновлений «нас обманывает», а ExecuteNonQuery возвращает 1, указывая на то, что она обновила строку, но на самом деле ее нет.Simple SqlCommand.ExecuteNonQuery всегда возвращает 1, даже когда он не обновлял базу данных

Если вы хотите сообщить мне, что не так с кодом, пожалуйста, продолжайте. То, на что я на самом деле надеюсь, является предложением о более «безумном» доказательстве способа обработки обновления. Может быть, было бы лучше установить соединение для использования транзакций? Может быть, гораздо лучше использовать хранимую процедуру, а также выполнять транзакции в хранимой процедуре? Насколько лучше/Почему?

код довольно просто (слишком просто?):

try 
{ 
    string sql = "UPDATE table SET barcode = '" + newBarcode + "' WHERE pk = '" + reportId + "'"; // no semicolon in the SQL 
    SqlCommand command = new SqlCommand(sql, connection); // connection recently opened 

    rowsUpdated = command.ExecuteNonQuery(); 

    if (rowsUpdated != 1) 
    { 
     connection.Close() 
     throw new Exception("..."); 
    } 
    else 
    ... 
    connection.Close(); 
} 
catch (Exception ex) 
... // general exceptions handled 
finally 
... // make sure connection is closed 

Я знаю, что это возможно (хотя очень маловероятно), что внешние воздействия могут быть аннулировав поле после обновления. Если это возможно, ТОЛЬКО возможность, прокомментируйте.

+2

Я хотел бы начать использовать параметризованный запрос. ASAP – Steve

+0

сделано. Теперь он более безопасен. Как вы думаете, это повлияет на результат возвращаемого значения? –

+0

Нет, только один пользователь. –

ответ

2

Обновление, которое обновляет строку до того же значения. по-прежнему считается пораженной строкой.

Сравните это со следующим:

UPDATE table SET barcode = @x WHERE pk = @id AND barcode <> @x 

Явный охранник пропустить эту строку, если обновление было «делать ничего», и, таким образом, он будет не учитываться как изменение, если нет необходимости вносить изменения.


В то время как один должен использовать заполнители (и using заявления) в зависимости от обстоятельств, ни один из них изменит результат обновления заявление.

1

Как и в другом ответе, используйте также запрограммированные запросы, используя оператор using, чтобы инициализировать соединение, поэтому вам не нужно брать на себя ответственность за его закрытие, когда вы закончите.

Также используйте параметр output и вместе с функцией @@ ROWCOUNT, чтобы узнать, обновлены ли какие-либо строки.

Используйте переменную RowsAffected для дальнейшей обработки.

using (SqlConnection conn = new SqlConnection("Connection string here...")) 
{ 
    string sqlcmd = "UPDATE table SET barcode = @newBarcode WHERE pk = @reportId SET @RowCount = @@ROWCOUNT;"; 

    conn.Open(); 
    SqlCommand cmd = new SqlCommand(sqlcmd, conn); 

    cmd.Parameters.Add("@RowCount", SqlDbType.Int).Direction = ParameterDirection.Output; 
    cmd.Parameters.Add(new SqlParameter("@newBarcode", newBarcode)); 
    cmd.Parameters.Add(new SqlParameter("@reportId", reportId)); 

    rowsUpdated = cmd.ExecuteNonQuery(); 
    int RowsAffected = Convert.ToInt32(cmd.Parameters["@RowCount"].Value); 

    if (RowsAffected == 0) 
    { 
     throw new Exception("..."); 
    } 
    else 
    ...... 
} 
0

Возвращаемое значение ExecuteNonQuery на запрос UPDATE является количество строк, соответствующих по ИНЕКЕ обновления заявление, а не от количества строк на самом деле обновляется.

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

Пожалуйста, обратитесь к https://bugs.mysql.com/bug.php?id=44194

Смежные вопросы