2016-09-12 11 views
0

Я унаследовал старый веб-сайт VB, который использует ExecuteNonQuery для изменения паролей. В нашей производственной среде, sql server 2008 R2, у меня были последние сообщения о неисправных функциях. Оказывается, ExecuteNonQuery возвращает -1, когда на самом деле данные обновляются (одна строка). Когда я копировал данные в нашу среду разработки, затронутые строки равны 1, как ожидалось. У нас есть разные пакеты обновления (4XXX против 6XXX), и мне интересно, если это проблема? Я изменил код, чтобы использовать ExecuteScalar для проверки RowCount, и это работает. Но я не должен был этого делать. Любое понимание? Теперь я знаю, как долго это было сломано.ExecuteNonQuery возвращает -1 (неправильно)

Вот оригинальный код, который возвращает -1 ошибочно. Это не вызов хранимой процедуры, и нет задействованных триггеров.

Dim cmd As SqlCommand = New SqlCommand("UPDATE UserMaster " & _ 
      " SET Password = @Password, LastPasswordChangedDate = @LastPasswordChangedDate " & _ 
      " WHERE Username = @UserName AND ApplicationName = @ApplicationName ", conn) 

    cmd.Parameters.Add("@Password", SqlDbType.VarChar, 255).Value = CreateHash(newPwd) 
    cmd.Parameters.Add("@LastPasswordChangedDate", SqlDbType.DateTime).Value = DateTime.Now 
    cmd.Parameters.Add("@Username", SqlDbType.VarChar, 255).Value = username.TrimEnd 
    cmd.Parameters.Add("@ApplicationName", SqlDbType.VarChar, 255).Value = Left(pApplicationName, 1) 

Dim rowsAffected As Integer = 0 
Try 
    conn.Open() 
    rowsAffected = cmd.ExecuteNonQuery() 

Этот код возвращает 1, как и ожидалось:

Dim cmd As SqlCommand = New SqlCommand("UPDATE UserMaster " & _ 
      " SET Password = @Password, LastPasswordChangedDate = @LastPasswordChangedDate " & _ 
      " WHERE Username = @UserName AND ApplicationName = @ApplicationName ; select @@rowcount", conn) 

    cmd.Parameters.Add("@Password", SqlDbType.VarChar, 255).Value = CreateHash(newPwd) 
    cmd.Parameters.Add("@LastPasswordChangedDate", SqlDbType.DateTime).Value = DateTime.Now 
    cmd.Parameters.Add("@Username", SqlDbType.VarChar, 255).Value = username.TrimEnd 
    cmd.Parameters.Add("@ApplicationName", SqlDbType.VarChar, 255).Value = Left(pApplicationName, 1) 

Dim rowsAffected As Integer = 0 
Try 
    conn.Open() 
    rowsAffected = CType(cmd.ExecuteScalar(), Integer) 
+0

'SET NOCOUNT OFF;' добавьте это перед обновлением. Когда он предотвращает появление дополнительных наборов результатов из-за вмешательства в предложения select ... Я не рекомендую этот подход, и вы должны его оставить ... Вы делаете простое обновление, поэтому это не должно быть проблемой. Другой вариант - объявить aupup param, а затем установите его после обновления. Когда вы выполняете, у вас будет номер строки ... Или просто выберите номер строки, как вы. – Codexer

+0

У вас есть триггер на этом столе? Если да, это может помочь (http://stackoverflow.com/a/15702169/1050927) – Prisoner

+0

@Alex OP сказал, что нет триггеров ... последнее предложение. – Codexer

ответ

0

ExceuteNonQuery возвращает -1 для всех хранимых процедур в соответствии с документацией Msdn.

Он вернет номер обновленных записей только в случае заявления.