IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ASP.NET Discussion :

Récupérer le résultat d'une requête "SELECT COUNT" en c#


Sujet :

ASP.NET

  1. #1
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 34
    Points : 21
    Points
    21
    Par défaut Récupérer le résultat d'une requête "SELECT COUNT" en c#
    Bonjour,

    Je suis depuis ce matin, en train d'essayer de faire un mini formulaire demandant à une personne diverses informations. J'aimerai vérifier, lors de la saisie de l'utilisateur, si l'e-mail saisi existe déjà ou non dans ma base de données.
    Du coup, lorsque l'utilisateur clique sur le bouton "Valider", j'ai une condition:
    un "if" qui vérifier si l'e-mail existe ou non et un "else" qui valide l'ajout de la personne.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Connect = new SqlConnection("Data Source=**");
                    Connect.Open();
     
                    SqlCommand Compte = new SqlCommand ("SELECT COUNT (UserEmail) FROM Utilisateur where UserEmail=@Email", Connect);
                    Selection.Parameters.Add("@Email", SqlDbType.NVarChar).Value=TextEmail.Text;
                    int resultSelection = Selection.ExecuteScalar();
     
                    if (resultSelection>0){
                        ConditionValidation.Text="L'e-mail saisi existe déjà. Veuillez recommencez.";
    }
    Le TextEmail correspond à la TextBox où l'utilisateur saisi son e-mail. Le ConditionValidation est un espace label où sera afficher l'erreur.

    Le hic, c'est que "Selection.ExecuteScalar()" se souligne en m'indiquant que l'on ne peut pas convertir implicitement le type "object" en int. Or, j'ai cherché sur pleins de forums ce souci, et beaucoup utilisent cette méthode pour la même chose, mais n'ont pas d'erreurs. J'ai bien sûr essayé avec le "ExecuteReader()" mais ça me pose le même soucis...

    Du coup je ne comprend pas mon erreur ni ne sait comment la résoudre.
    Quelqu'un peut-il m'éclairer?

  2. #2
    Membre éprouvé Avatar de Momoth
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2013
    Messages
    318
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 318
    Points : 1 236
    Points
    1 236
    Par défaut
    Bonjour,

    Essaye de caster le retourner d'ExecuteScalar en int. Cette méthode te retourne un object, car elle te retourne le contenu de la première colonne de la première ligne affecté (qui n'est pas forcément un int). Si cela ne marche pas, tu peux utiliser sinon la méthode ExecuteNonQuery a la place d'ExecuteScalar. ExecuteNonQuery te retourne le nombre de ligne affecté par ta requête.
    La Triforce du développement : Fainéantise, Curiosité et Imagination.

  3. #3
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 34
    Points : 21
    Points
    21
    Par défaut
    Bonjour Momoth,

    Merci pour ton aide. J'ai essayé les deux solutions.

    Pour le cast, j'ai remplacé par cette ligne de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int resultSelection = int(Selection.ExecuteScalar());
    Pourtant, cela ne donne "aucun résultat". Dans le sens où, quand je tape une adresse email qui se trouve déjà dans ma base de donnée, la saisie est acceptée et rajoutée dans ma base de donnée. J'ai également essayé le ExecuteNonQuery(), et j'ai le même résultat..
    Aurais-tu une idée du pourquoi? Mon code est-il faut? Est-ce que je fais la bonne démarche pour obtenir ce résultat?

  4. #4
    Membre éprouvé Avatar de Momoth
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2013
    Messages
    318
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 318
    Points : 1 236
    Points
    1 236
    Par défaut
    Bonjour,

    Quand tu dis que cela ne donne aucun résultat c'est à dire ? Que te retournes les méthodes ExecuteScalar et ExecuteNonQuery ? Que contient resultSelection au moment du if ligne 9 ?

    Essaye de mettre un point d’arrêt sur cette ligne pour voir le résultat.
    La Triforce du développement : Fainéantise, Curiosité et Imagination.

  5. #5
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 34
    Points : 21
    Points
    21
    Par défaut
    Excuse moi de ne te répondre que maintenant, je n'avais pas vu ta réponse...

    Je suis désolée, je n'ai pas assez bien expliqué mon site web. Donc en fait, je développe un petit truc tout bête en WebForm ASP.NET c#. Un utilisateur arrive sur une page web de type formulaire, comme une page pour s'inscrire. Dedans, il y a diverses informations à remplir comme l'e-mail. Or, avant d'ajouter cette personne dans ma base de données, j'aimerai vérifier d'abord si l'e-mail qu'elle saisie ne s'y trouve pas déjà. Avec ce code, quand je lance mon appli, et que je tape une adresse mail déjà existante, cela m'insère toujours une autre personne...

    Par rapport au code que je t'ai montré juste avant, quand je cast, une "mini" erreur apparaît à la première parenthèse disant que le terme d'expression 'int' est non valide.

    Quand je lance mon appli, avec différents points d'arrêt, j'obtiens la valeur '0' avec ExecuteNonQuery(), et la valeur -1 dans mon if pour 'resultSelection':


    Nom : premierpointdarret.jpg
Affichages : 5138
Taille : 14,4 Ko

    Nom : dexuiemepointdarret.jpg
Affichages : 5069
Taille : 14,9 Ko

    J'ai écris ce code suivant "ma logique", en me disant qu'en comptant le nombre de fois où l'e-mail saisi apparait dans ma base de données, je pourrai savoir si celui-ci existe ou non... Mais peut-être que ce n'est pas une bonne idée et que ma démarche est fausse. Le problème c'est que je ne vois pas une autre façon de faire, pour le moment.


    EDIT:
    J'ai essayé de changé ma condition en écrivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
                    if (resultSelection != (0))
                    {
                        ConditionValidation.Text = "L'e-mail saisi existe déjà.";
                    }
    Mais 'resultCondition' vaut toujours (-1).
    Mon message s'affiche bien, le problème c'est qu'il s'affiche même quand l'adresse mail n'existe pas... Donc fais tout le contraire..
    J'ai testé ma requête SQL en remplaçant "@email" par un e-mail déjà existant et elle me renvoie bien '1' ou '0' quand j'écris un e-mail non existant. Donc je ne pense pas que ma requête soit fausse...

  6. #6
    Membre éprouvé Avatar de Momoth
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2013
    Messages
    318
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 318
    Points : 1 236
    Points
    1 236
    Par défaut
    T'excuse pas en fait c'est moi qui est mal lu ton code. Pour récupérer le retour d'une requete select tu dois faire un reader de ta requete comme ceci.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SqlCommand Compte = new SqlCommand ("SELECT COUNT (UserEmail) as nbMail FROM Utilisateur where UserEmail=@Email", Connect);
    Compte.Parameters.Add("@Email", SqlDbType.NVarChar).Value=TextEmail.Text;
    SqlDataReader reader = Compte.ExecuteReader();
    int nbMail;
    while (reader.Read())
    {
           nbMail = (int)reader["nbMail"];
    }
    Donc l'idée, c'est de donné un nom au count de ta requete sql et ensuite, via le reader tu récupère sa valeur. Essayes quelque chose comme ca.
    La Triforce du développement : Fainéantise, Curiosité et Imagination.

  7. #7
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 34
    Points : 21
    Points
    21
    Par défaut
    Merci Momoth,

    Tu viens de réussir à régler mon problème !! J'ai fermé ma boucle après mes conditions if/else, en prenant le soin de ne pas oublier de fermer mon DataReader dans mon else.
    Pour ceux qui sont intéressés ou qui ont le même problème, voici une idée du code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    SqlCommand Compte = new SqlCommand ("SELECT COUNT (UserEmail) as nbMail FROM Utilisateur where UserEmail=@Email", Connect);
    Compte.Parameters.Add("@Email", SqlDbType.NVarChar).Value=TextEmail.Text;
    SqlDataReader reader = Compte.ExecuteReader();
    int nbMail;
    while (reader.Read())
    {
           nbMail = (int)reader["nbMail"];
           if (nbMail > 0)
                        {
                            ConditionValidation.Text = "L'e-mail saisi existe déjà.";
                        }
                        else
                        {
                            reader.Close();
                            // + ici, conditions à écrire si l'e-mail n'existe pas déjà dans la base.
                        }
    }
    Je te remercie encore Momoth d'avoir pris la patience de m'expliquer et d'avoir réussi à régler mon problème .

  8. #8
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Points : 3 173
    Points
    3 173
    Par défaut
    Il y a de tout et n'import quoi dans ce code:
    Dans ton premier post, le code est faux, la parameter ajouté ne l'est pas sur le sqlcommand (mais on ne voit pas tout ton code): ta SqlCommand s'appel compte et tu ajoute le paramètre email a un objet qui s'appel selection

    En fait la meilleur solution est celle que tu avais tenté au début: c'est bien un ExecuteScalar casté en int qui convient le mieux.

    En revanche pourquoi compter le nombre de compte avec un email alors que vous voulez seulement savoir s'il existe?

    La requète suivante est plus appropriée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT CASE WHEN EXISTS(SELECT * FROM Utilisateur where UserEmail=@Email) THEN 1 ELSE 0 END
    C'est plus performant et vous récupérez directement un booléen.


    PS: pensez à fermer la connection à la fin...
    Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
    MCTS Database Development
    MCTS Database Administration

  9. #9
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Euh...

    Pour caster un object en int, c'est :
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (int)myObject
    Et non
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int(myObject)

    Ensuite, ExecuteNonQuery retourne le nombre de lignes concernées par la requête... mais pas toujours !
    Selon le type de jointures, d’agrégats, le type de curseur, et surtout, le SGBD et la version du pilote, il peut aussi retourner -1, ou un résultat complètement farfelu !

    Donc pour récupérer le résultat d'un COUNT(*), il n'y a qu'une seule méthode à utiliser : ExecuteScalar, en faisant un cast correctement !

    Citation Envoyé par Momoth Voir le message
    Donc l'idée, c'est de donné un nom au count de ta requete sql et ensuite, via le reader tu récupère sa valeur. Essayes quelque chose comme ca.
    Outre que le fait d'utiliser un DataReader pour lire une unique colonne dans une unique ligne sur un unique jeu de résultat est aussi inutile que contre-performant, un Reader n'a pas besoin de colonnes nommées pour fonctionner !

    On peut parfaitement utiliser :
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    reader.GetInt(0);
    Pourrécupérer le int qui se trouve dans la première colonne.

    Car passer par un accesseur oblige en interne .NET à fait tout un tas de traitements inutiles :
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    reader.ToArray()[reader.GetOrdinal("macolonne")]
    On ne jouit bien que de ce qu’on partage.

  10. #10
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Points : 3 173
    Points
    3 173
    Par défaut
    +1 pour string builder 100% daccord même si il y a plus simple que ca:
    reader.ToArray()[reader.GetOrdinal("macolonne")]
    Celà fonctionne aussi:
    Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
    MCTS Database Development
    MCTS Database Administration

  11. #11
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par iberserk Voir le message
    +1 pour string builder 100% daccord même si il y a plus simple que ca:

    Celà fonctionne aussi:
    C'est justement à cette syntaxe que je réagissais : en interne, l'accesseur directement sur le DataReader se transforme en ToArray() + GetOrdinal(), deux opération inutiles si on fait directement un GetInt()
    On ne jouit bien que de ce qu’on partage.

  12. #12
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 34
    Points : 21
    Points
    21
    Par défaut
    Bonjour à tous,

    Désolée de ne répondre que maintenant, je n'ai pas été chez moi du weekend...

    iberserk, je viens de me rendre compte que mon premier code est incohérent dans le nom de mes variables et je m'en excuse sincèrement. A ce moment-là, j'ai du changer le nom de mes variables ou faire une fausse manip' ctrl+z et je ne l'ai pas vu en copiant mon code. Désolée.
    Comme je le disais plus haut, je n'étais pas sûr de ma démarche, et c'est aussi pour cela que je demandais des conseils. Il est vrai que je n'avais pas du tout penser à la requête que tu as écris, et je t'en remercie. J'ai essayé, le code en est plus simple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SqlCommand verifEmail = new SqlCommand("SELECT CASE WHEN EXISTS(SELECT CASE WHEN EXISTS(SELECT * FROM Utilisateur where UserEmail=@Email) THEN 1 ELSE 0 END", Connect);
    verifEmail.Parameters.Add("@Email", SqlDbType.NVarChar).Value = TextEmail.Text;
    int resultverifEmail = (int)verifEmail.ExecuteScalar();
     
    if (resultverifEmail == 1)
         {          
           ConditionValidation.Text = "L'e-mail saisi existe déjà.";
          }

    StringBuilder, je te remercie également pour ton aide. J'ai pu voir mon erreur de cast, qui est une erreur un peu débile mais c'est comme oublier un point virgule et passer 3heures à chercher l'erreur sans la voir... Tu m'as également éclairer sur l'utilisation du DataReader, et je t'en remercie.

    iberserk, je voulais juste mettre l'essentiel de mon code. Veux-tu que je te montre tout le code? Pour ce qui est de la connexion, mon code est dans un "try/catch" pour gérer les exceptions, et je ferme ma connexion dans un "finally".

    En tout cas, merci à vous deux et à Momoth de m'avoir aidé, et surtout de m'avoir bien tout expliqué, j'en sors que plus grande .

  13. #13
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Points : 3 173
    Points
    3 173
    Par défaut
    Citation Envoyé par Limoen Voir le message
    je voulais juste mettre l'essentiel de mon code. Veux-tu que je te montre tout le code? Pour ce qui est de la connexion, mon code est dans un "try/catch" pour gérer les exceptions, et je ferme ma connexion dans un "finally"..

    Préferez l'utilisation de using pour le sqlcommand:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    using (SqlCommand cmd=new SqlCommand("marequete",new SqlConnection("machainedeconnexion")))
    {
     
    }
    Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
    MCTS Database Development
    MCTS Database Administration

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. récupérer le résultat d'une requête select en c#
    Par chemsoun dans le forum Unity
    Réponses: 1
    Dernier message: 12/04/2015, 10h06
  2. Réponses: 10
    Dernier message: 13/09/2011, 17h24
  3. Réponses: 3
    Dernier message: 16/10/2005, 11h53
  4. récupérer le résultat d'une requête sql dans un edit
    Par bertrand_declerck dans le forum Bases de données
    Réponses: 3
    Dernier message: 28/07/2005, 14h07
  5. Réponses: 7
    Dernier message: 30/06/2005, 10h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo