2016-09-12 3 views
0

J'ai hérité d'un ancien site Web VB qui utilise ExecuteNonQuery pour modifier les mots de passe. Dans notre environnement de production, sql server 2008 R2, j'ai eu des rapports récents de fonctionnalités cassées. Il s'avère que ExecuteNonQuery renvoie -1 alors qu'en réalité les données sont mises à jour (une seule ligne). Lorsque j'ai copié les données dans notre environnement de développement, les lignes affectées sont 1 comme prévu. Nous avons un service packs différent appliqué (4XXX vs 6XXX) et je me demande si c'est le problème? J'ai modifié le code pour utiliser ExecuteScalar pour inspecter le RowCount, et cela fonctionne. Mais je ne devrais pas avoir à le faire. Un aperçu? J'ai maintenant une idée de combien de temps cela a été brisé.ExecuteNonQuery renvoie -1 (incorrectement)

Voici le code original, qui renvoie -1 à tort. Il n'appelle pas de procédure stockée et aucun déclencheur n'est impliqué.

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() 

Ce code renvoie un 1 comme prévu:

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;' ajouter cela avant votre mise à jour. Lorsqu'il est activé, cela empêche les ensembles de résultats supplémentaires d'interférer avec les instructions select ... Je ne recommande pas cette approche et vous devriez la laisser sur ... Vous faites une mise à jour simple, donc ça ne devrait pas poser de problème. un paramètre ouput, puis définissez-le après la mise à jour. Une fois exécuté, vous auriez le rowcount ... Ou juste sélectionnez le rowcount comme vous êtes. – Codexer

+0

Avez-vous un déclencheur sur cette table? Si oui, cela pourrait être utile (http://stackoverflow.com/a/15702169/1050927) – Prisoner

+0

@Alex OP a dit qu'il n'y a pas de déclencheurs ... dernière phrase. – Codexer

Répondre

0

ExceuteNonQuery retourne -1 pour toutes les procédures stockées que par la documentation Msdn.

Il ne renverra le numéro des enregistrements mis à jour que dans le cas d'une déclaration.