2010-08-13 3 views
1

Je rencontre un problème étrange lorsque j'essaie d'exécuter une requête DELETE sur une table SQL Server à l'aide de VB.NET, SQL Command et Parameters.Sqlcommand Paramètres non exécutés

J'ai le code suivant:

Try  
    sqlCommand.Transaction = transaction1 
    sqlCommand.Connection = conn 
    sqlCommand.CommandText = sqlQuery 
    sqlCommand.Parameters.Add("@userID", SqlDbType.Int).Value = Convert.ToInt32(userID) 
    sqlCommand.Parameters.Add("@groupID", SqlDbType.Int).Value = Convert.ToInt32(groupID) 
    ''#Delete the user from the group. 
    MessageBox.Show("User: " + Convert.ToString(userID) + " Group: " + Convert.ToString(groupID)) 
    MessageBox.Show("Param, UserID: " + sqlCommand.Parameters.Item(0).Value.ToString) 
    MessageBox.Show("Param, GroupID: " + sqlCommand.Parameters.Item(1).Value.ToString) 
    return_deleteUser = sqlCommand.ExecuteNonQuery() 
Catch ex As Exception 
    transaction1.Rollback() 
    Dim hr As Integer = Marshal.GetHRForException(ex) 
    MsgBox("Removal of user from group has failed: " + ex.Message() & hr) 
End Try 

qui exécute la requête SQL suivante:

Dim sqlQuery As String = "DELETE FROM MHGROUP.GROUPMEMS WHERE USERNUM [email protected] AND GROUPNUM [email protected]" 

Mon problème est que lorsque le code est exécuté, il n'y a pas d'erreur rapporté du tout. J'ai couru le profileur SQL et la requête n'apparaît pas dans la liste de trace. Les trois boîtes de message que j'ai ajoutées tous retournent les valeurs correctes, et si je devais exécuter la requête SQL contre la table avec les valeurs la requête réussit. L'ID utilisateur et l'ID groupe sont tous les deux des entiers à 3 chiffres. Est-ce que quelqu'un peut suggérer pourquoi le code ne fonctionne pas comme prévu, ou n'importe quel autre débogage que je peux utiliser pour parcourir le code?

Idéalement, j'aimerais voir la requête SQL terminée avec les paramètres terminés, mais je n'ai pas trouvé comment faire cela.

EDIT: Je les suivantes plus tard dans le code pour vérifier si l'ensemble exécutons traités avec succès:

If return_insertEvent > 0 And return_updateUser > 0 And return_nextSID > 0 And return_deleteUser > 0 Then 
    MessageBox.Show("Success") 
    return_removeADGroup = RemoveUserFromGroup(userID, groupName) 
    MessageBox.Show("Remove FS User from AD Group: " + return_removeADGroup) 
    transaction1.Commit() 
    transaction2.Commit() 
    transaction3.Commit() 
    transaction4.Commit() 
    returnResult = 1 
Else 
    transaction1.Rollback() 
    transaction2.Rollback() 
    transaction3.Rollback() 
    transaction4.Rollback() 
    returnResult = 0 
End If 

Si vous avez besoin de plus amples informations s'il vous plaît ne hésitez pas à me contacter.

+0

Avez-vous vérifié que transaction.Commit est appelé? –

Répondre

4

Il vous manque un Transaction.Commit

Mise à jour dans respone à info supplémentaire ajoutée à la question:

Pourquoi avez-vous 4 transactions? Puisque leurs commit et rollbacks sont tous exécutés ensemble, vous n'avez besoin que d'une transaction. Je vous suggère d'utiliser un TransactionScope

Vous pouvez attribuer la transaction en cours aux objets ADO.NET Commande:

ADO.NET and System.Transactions

Transaction Processing in ADO.NET 2.0

+0

Celles-ci étaient présentes plus tard dans le code, elles sont incluses dans un IF ... ELSE pour s'assurer que les transactions ne sont validées que si TOUTES les transactions ont abouti. – Lima

+0

@Lima - ne mélangez pas plusieurs transactions de ce type. Vous pouvez et devez utiliser la même transaction sur plusieurs commandes. –

+0

Pouvez-vous fournir des informations/des liens sur la façon dont je peux réaliser une transaction pour les quatre requêtes? Je préférerais beaucoup cela car c'est le code le plus propre, mais je ne sais pas comment y parvenir. – Lima

1

Je pourrais deviner que votre appel proc a les valeurs de code d'utilisateur et groupid en arrière. Si le DELETE ne trouve pas un enregistrement correspondant, il se terminera avec succès, mais ne fera rien. Je suggère d'encapsuler votre suppression dans une procédure stockée. Ensuite, vous pouvez ajouter du code pour tester si les valeurs des paramètres passent correctement.

Create Procedure UserDelete 
@userid int, @groupID int 
As 
BEGIN 
    Select @userid as UID, @groupID as GID INTO TESTTABLE; 
    DELETE FROM MHGROUP.GROUPMEMS WHERE USERNUM [email protected] AND GROUPNUM [email protected]; 
END 

Exécutez votre code, puis vérifiez le contenu de TESTTABLE. FWIW: Je n'aime pas essayer d'obtenir la déclaration complète des paramètres sur une seule ligne. Trop de choses pour moi. Ça me plaît ...

Dim pUID as New Parameter("@userid", SqlDbType.Int) 
pUID.Value = userid 
cmd.Parameters.Add(pUID) 
+0

Les @userID et @groupID sont les deux valeurs correctes et les requêtes s'exécutent correctement lors de l'utilisation de studio de gestion. Je préférerais ne pas créer un nouveau SP pour ce genre de requêtes car je finirais avec une grande quantité de SP (je compte au moins 16 pour ce projet). – Lima

0

Après un certain temps de débogage et de traçage sql, j'ai trouvé que l'application stupide que la DB appartient à traite différemment les membres du groupe, les groupes résident dans une base de données d'administration, mais la l'appartenance des utilisateurs au groupe réside dans une autre base de données.

Merci à tous ceux qui vous ont fourni du temps et des idées pour vous aider avec le code. J'ai changé le code comme recomended pour utiliser seulement deux transactions et deux connexions (1 pour l'admin et la sous-base de données). Le code est beaucoup plus agréable maintenant et est un peu plus facile à lire.

Merci encore,

Matt

Questions connexes