Partage
  • Partager sur Facebook
  • Partager sur Twitter

probleme dans une fonction

la référence d'objet n'est pas définie à une instance d'un objet

    28 mai 2019 à 17:24:16

    Bonjour,

    J'ai un petit soucie avec mon code. Dans ma fonction "getLastInsertedIdVisite" j'ai définie la valeur "idVisite", cependant celui-ci me retourne l'erreur suivante : la référence d'objet n'est pas définie à une instance d'un objet.

    voici la partie du code concerné :

    // Récupération du dernier identifiant de la table Visite + 1.
            static public int getLastInsertedIdVisite()
            {
                int count = 0;
                SqlCommand uneCommande = new SqlCommand("getLastInsertedIdVisite", maConnexion);
                uneCommande.CommandType = System.Data.CommandType.StoredProcedure;
                uneCommande.Parameters.Add("idVisite", System.Data.SqlDbType.Int);
                uneCommande.Parameters["idVisite"].Direction = System.Data.ParameterDirection.Output;
                int idVisite = (int)uneCommande.Parameters["idVisite"].Value;
                SqlDataReader unCurseur = uneCommande.ExecuteReader();
    
                while (unCurseur.Read())
                {
                    count = (int)unCurseur["maxId"];
                }
                unCurseur.Close(); // A NE PAS SUPPRIMER BAKEMONO !!!!
                return count;
            }



    • Partager sur Facebook
    • Partager sur Twitter
      29 mai 2019 à 9:38:43

      Salut,

      J'ai pas touché à SQL depuis PHP5, mais je ne comprends déjà pas cette ligne :

      SqlCommand uneCommande = new SqlCommand("getLastInsertedIdVisite", maConnexion);

      Tu n'es pas censé donner une query en 1er paramètre du constructeur de SqlCommand ?

      Et quelle est la valeur de maConnexion ?

      -
      Edité par galactose 29 mai 2019 à 9:39:50

      • Partager sur Facebook
      • Partager sur Twitter
        29 mai 2019 à 15:25:09

        Bonjour,

        Merci d'avoir prit du temps pour donner une réponse a mon problème. Je vais fournir le début de mon code pour que vous puissez mieux comprendre la commande "SqlCommande".

        static private ConnectionStringSettings uneChaine = ConfigurationManager.ConnectionStrings["sgbd"];
                static private string maChaineDeConnexion = uneChaine.ConnectionString;
                static private SqlConnection maConnexion = new SqlConnection(maChaineDeConnexion);
        
                internal static Donnee chargerDonnees()
                {
                    throw new NotImplementedException();
                }

        Et voici la classe "Global" au cas ou sa peut aider à mieux comprendre:

        class Globale
            {
                // données globale de l'application
                // db : les données en mémoire
                // levisiteur : l'objet visiteur connecté
                public static Donnee db;
                public static Visiteur leVisiteur = null;
            }



        Si par ailleur vous souhaitez avoir l'enssembe de la classe sur laquel je travaille pour comprendre mon projet dans son intégralité n'hésitez pas à me le demander.

        Cdt

        -
        Edité par IdrissNgou 29 mai 2019 à 15:29:47

        • Partager sur Facebook
        • Partager sur Twitter
          30 mai 2019 à 4:52:20

          Vous ne donnez effectivement pas de requête SQL dans votre code. Il n'y a pas de paramètre à remplir.

          Aussi, vous ne 'settez' à aucun moment la valeur de votre paramètre.

          SqlConnection con = new SqlConnection(@"Data Source=C:\Users\Lily\source\repos\KerberosMcWrapp\local.db;");
          
                      SqlCommand uneCommande = new SqlCommand("SELECT * FROM table WHERE ID = @idVisite", con);
          
                      //-----//
          
                      uneCommande.Parameters.Add("@idVisite", System.Data.SqlDbType.Int);
                      uneCommande.Parameters["@idVisite"].Value = 2;
          
                      // OR //
          
                      uneCommande.Parameters.AddWithValue("@idVisite", 3);
          
                      //-----//
          
                      int idVisite = (int)uneCommande.Parameters["@idVisite"].Value;


          -
          Edité par LilyKianii 30 mai 2019 à 4:54:22

          • Partager sur Facebook
          • Partager sur Twitter
            30 mai 2019 à 13:50:34

            Bonjour,

            Après avoir effectué les modifications que vous m'avez suggéré, cela semble avoir corrigé le problème d'ajout. Cependant une nouvelle erreur a été signalé après que je ne comprends pas.

            L'érreur signalé est : System.IndexOutOfRangeException : 'maxId'

            voici le code:

            static public int getLastInsertedIdVisite()
                    {
                        int count = 0;
                        SqlConnection sqlConnection = new SqlConnection(@"Data Source = C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\GSB.mdf;");
                        SqlCommand uneCommande = new SqlCommand("SELECT * FROM visite WHERE id = @idVisite", maConnexion);
                        uneCommande.Parameters.AddWithValue("@idVisite", 3);
                        int idVisite = (int)uneCommande.Parameters["@idVisite"].Value;
                        SqlDataReader unCurseur = uneCommande.ExecuteReader();
            
                        while (unCurseur.Read())
                        {
                            count = (int)unCurseur["maxId"];
                        }
                        unCurseur.Close(); // A NE PAS SUPPRIMER BAKEMONO !!!!
                        return count;
                    }



            -
            Edité par IdrissNgou 30 mai 2019 à 13:53:27

            • Partager sur Facebook
            • Partager sur Twitter
              30 mai 2019 à 14:56:49

              Étant donné que vous n'avez pas l'erreur vous rappelant d'ouvrir la connexion avant toute lecture, je considère que vous l'avez fait plus haut.

              Aussi, l'erreur vous indique ici que maxId n'est pas un header de colonne existant dans votre dataset récupéré via la lecture.

              Si aucune valeur n'eût été existante dans la table, vous ne seriez probablement pas rentré dans votre boucle Read().

              Je me pose donc les questions suivantes :

              • Êtes-vous certains de la syntaxe de maxId ?
              • Est-ce bien une colonne de la table visite ?

              -
              Edité par LilyKianii 30 mai 2019 à 14:59:32

              • Partager sur Facebook
              • Partager sur Twitter
                30 mai 2019 à 18:59:50

                Merci pour ce retour je confirme que "MaxId" n'est pas une colonne de la table "Visite", mais du coup comment faire pour récupérer le max de L'id de cette table après l'avoir compter ?

                PS: j'ai tenté de modifier MaxId par une colonne existante et j'ai toujours la même erreur.

                -
                Edité par IdrissNgou 30 mai 2019 à 19:23:36

                • Partager sur Facebook
                • Partager sur Twitter
                  31 mai 2019 à 15:32:02

                  IdrissNgou a écrit:

                  Merci pour ce retour je confirme que "MaxId" n'est pas une colonne de la table "Visite", mais du coup comment faire pour récupérer le max de L'id de cette table après l'avoir compter ?

                  SELECT MAX(idVisite) FROM visite

                  Notez que ceci vous renvoie la valeur maximale,  pas forcément la dernière valeur insérée. Évitez donc de toucher vous même aux ID et laissez l'auto-incrémentation faire son travail.

                  Une autre façon de faire, plus sécure mais plus complexe également ; est de rajouter une colonne qui sera là seulement pour indiquer la dernière ligne insérée / modifiée.

                  Chaque méthode a ses avantages... et ses inconvénients. Je pense que pour chercher la dernière insertion, la première fait parfaitement l'affaire.

                  IdrissNgou a écrit:

                  PS: j'ai tenté de modifier MaxId par une colonne existante et j'ai toujours la même erreur.

                  Même questions qu'au message précédemment. Êtes-vous sûrs de la syntaxe ? Si oui, je ne vois pas trop. Il serait peut être plus simple de vous épauler avec la structure de la base de donnée.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    31 mai 2019 à 16:27:29

                    Merci du retour,

                    j'ai effectué la modification suivante(corrigé la svp si c'est pas bon):

                    static public int getLastInsertedIdVisite()
                            {
                                int count = 0;
                                SqlConnection sqlConnection = new SqlConnection(@"Data Source = C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\GSB.mdf;");
                                SqlCommand uneCommande = new SqlCommand("SELECT * FROM visite WHERE id = @idVisite", maConnexion);
                                uneCommande.Parameters.AddWithValue("@idVisite", 3);
                                int idVisite = (int)uneCommande.Parameters["@idVisite"].Value;
                                SqlCommand command = new SqlCommand("SELECT MAX(idVisite) FROM visite");
                                //SqlDataReader unCurseur = uneCommande.ExecuteReader();
                    
                                /*while (unCurseur.Read())
                                {
                                    count = (int)unCurseur["@idVisite"];
                                }
                                unCurseur.Close();*/ // A NE PAS SUPPRIMER BAKEMONO !!!!
                                return count;
                            }

                    mais pour finir j'obtien un resultat innatendu que voici:


                     et voici ma fonction "ajouterVisite":

                    static public bool ajouterVisite(Visiteur unVisiteur, Praticien unPraticien, Motif unMotif, DateTime uneDate, string bilan)
                            {
                                bool ok;
                                try
                                {
                                    maConnexion.Open();
                                }
                                catch
                                {
                                    ok = false;
                                    MessageBox.Show("Erreur ");
                                }
                    
                                SqlCommand uneCommande = new SqlCommand("ajouterVisite", maConnexion);
                                uneCommande.CommandType = System.Data.CommandType.StoredProcedure;
                                int id = getLastInsertedIdVisite() +1;
                                MessageBox.Show("id Visiteur : " + Globale.leVisiteur.getId()+ "id Visite: " + id);
                                uneCommande.Parameters.AddWithValue("idVisite", id);
                                uneCommande.Parameters.AddWithValue("idVisiteur", Globale.leVisiteur.getId());
                                uneCommande.Parameters.AddWithValue("idPraticien", unPraticien.getId());
                                uneCommande.Parameters.AddWithValue("idMotif", unMotif.getId());
                                uneCommande.Parameters.AddWithValue("dateVisite", uneDate);
                                uneCommande.Parameters.AddWithValue("bilan", bilan);
                    
                                try
                                {
                                    uneCommande.ExecuteNonQuery();
                                    ok = true;
                                    MessageBox.Show("Ajout réussi.");
                                }
                                catch (Exception e)
                                {
                                    ok = false;
                                    MessageBox.Show(e.ToString());
                                }
                                finally
                                {
                                    maConnexion.Close();
                                }   
                                
                                return ok;
                            }
                     class Globale
                        {
                            // données globale de l'application
                            // db : les données en mémoire
                            // levisiteur : l'objet visiteur connecté
                            public static Donnee db;
                            public static Visiteur leVisiteur = null;
                        }




                    -
                    Edité par IdrissNgou 31 mai 2019 à 17:24:26

                    • Partager sur Facebook
                    • Partager sur Twitter
                      31 mai 2019 à 18:29:35

                      I)_ L'erreur tout d'abord.
                      Elle est assez explicite : ajouterVisite attend en paramètre '@idVisiteur'. Hors, vous ne fournissez pas ce paramètre dans votre code. 

                      II)_ Ensuite, vous essayez de récupérer le dernier ID de la table visite pour ensuite l'incrémenter et vous en servir pour la prochaine insertion... VADE RETRO ! J'ai pas pris une journée de congés pour voir ça ! :colere:

                      La solution est la suivante : lors de la création de votre base de donnée SQL, il vous est possible de faire de votre colonne ID une colonne en auto-incrémentation. Cela signifie que vous n'avez pas à spécifier l'ID lors de vos insertions et que SQL se chargera lui-même de récupérer le dernier ID et d'en augmenter sa valeur. Pratique nan ?

                      III)_ Aussi, et même si ce n'est plus nécessaire en appliquant la "politique de l'auto-incrémentation", votre fonction getLastInsertedVisite() comporte beaucoup de code superflu, ce qui me porte à croire que vous n'avez pas encore tout saisi du principe de requête SQL.

                      Erreur 1 : 'count' n'est pas un bon nom de variable à retourner. Cela marche, certes, mais ce serait plus parlant de lui donner un nom en rapport avec ce qu'il est : un ID !

                      Erreur 2 : Le code ci-dessous ne sert pas (je suppose que c'est lié au fait que vous n'avez pas nettoyé votre ancien code mais je le souligne tout de même).

                      IdrissNgou a écrit:

                      SqlConnection sqlConnection = new SqlConnection(@"Data Source = C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\GSB.mdf;");
                      SqlCommand uneCommande = new SqlCommand("SELECT * FROM visite WHERE id = @idVisite", maConnexion);
                      uneCommande.Parameters.AddWithValue("@idVisite", 3);
                      int idVisite = (int)uneCommande.Parameters["@idVisite"].Value;

                      La première ligne ne sert pas car vous avez déjà défini une connexion. Celle-ci n'est pas ouverte, vous ne pouvez donc pas l'utiliser ici.
                      La ligne 2 et 3 ne correspondent pas à ce que vous attendez de la fonction. Encore une fois, c'est probablement que vous n'avez pas encore nettoyé votre ancien code.
                      La ligne 4 n'est pas nécessaire car vous essayez de faire une lecture. C'est juste un debug qui vous permet de mettre en valeur l'ajout de paramètre fait à la ligne 3. Ce n'est pas à mettre dans votre code "final".

                      Erreur 3 : Vous n'avez probablement pas de colonne nommé '@idViste'. Les @ sont utilisés pour l'ajout de paramètres dans une requête. Ici, vous essayez de récupérer ce que vous avez lu. On y attend l'index de votre colonne OU son nom.

                      IdrissNgou a écrit:

                      count = (int)unCurseur["@idVisite"];

                      IV)_ Enfin, dans votre fonction ajouterVisite(), pourquoi utilisez-vous 'leVisiteur' de votre classe Globale alors que vous passez justement un Visiteur en paramètre de la fonction. Il serait plus judicieux d'utiliser unVisiteur.getId() pour votre paramètre @idVisiteur.

                      -
                      Edité par LilyKianii 31 mai 2019 à 18:32:30

                      • Partager sur Facebook
                      • Partager sur Twitter
                        31 mai 2019 à 22:05:48

                        Bonsoir,

                        tout d'abord je tiens à vous remercier pour tous ses retours ça m'aide beaucoup. Vue que je suis étudiant en informatique j'apprends beaucoup grâce à vous merci :).

                        Pour en revenir au code pouvez-vous svp me proposer des idées de correction svp car et tant donné que les retours prennent un peu de temps je pourrais ainsi analyser en détails vos propositions.

                        Voici mon code avec les dernières modifications proposées (bien entendu je nettoierai le code une fois l'application fonctionnelle) :

                        static public int getLastInsertedIdVisite()
                                {
                                    int id = 0;
                                    /*SqlConnection sqlConnection = new SqlConnection(@"Data Source = C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\GSB.mdf;");
                                    SqlCommand uneCommande = new SqlCommand("SELECT * FROM visite WHERE id = @idVisite", maConnexion);
                                    uneCommande.Parameters.AddWithValue("@idVisite", 3);
                                    int idVisite = (int)uneCommande.Parameters["@idVisite"].Value;*/
                                    SqlCommand command = new SqlCommand("SELECT MAX(id) FROM visite");
                                    
                                    /*SqlDataReader unCurseur = uneCommande.ExecuteReader();
                        
                                    while (unCurseur.Read())
                                    {
                                        count = (int)unCurseur["@idVisite"];
                                    }
                                    unCurseur.Close(); A NE PAS SUPPRIMER BAKEMONO !!!!
                                    */
                                    return id;
                                }
                        
                                static public bool ajouterVisite(Visiteur unVisiteur, Praticien unPraticien, Motif unMotif, DateTime uneDate, string bilan)
                                {
                                    bool ok;
                                    try
                                    {
                                        maConnexion.Open();
                                    }
                                    catch
                                    {
                                        ok = false;
                                        MessageBox.Show("Erreur ");
                                    }
                        
                                    SqlCommand uneCommande = new SqlCommand("ajouterVisite", maConnexion);
                                    uneCommande.CommandType = System.Data.CommandType.StoredProcedure;
                                    int id = getLastInsertedIdVisite() +1;
                                    MessageBox.Show("id Visiteur : " + unVisiteur.getId()+ "id Visite: " + id);
                                    uneCommande.Parameters.AddWithValue("idVisite", id);
                                    uneCommande.Parameters.AddWithValue("idVisiteur", unVisiteur.getId());
                                    uneCommande.Parameters.AddWithValue("idPraticien", unPraticien.getId());
                                    uneCommande.Parameters.AddWithValue("idMotif", unMotif.getId());
                                    uneCommande.Parameters.AddWithValue("dateVisite", uneDate);
                                    uneCommande.Parameters.AddWithValue("bilan", bilan);
                        
                                    try
                                    {
                                        uneCommande.ExecuteNonQuery();
                                        ok = true;
                                        MessageBox.Show("Ajout réussi.");
                                    }
                                    catch (Exception e)
                                    {
                                        ok = false;
                                        MessageBox.Show(e.ToString());
                                    }
                                    finally
                                    {
                                        maConnexion.Close();
                                    }   
                                    
                                    return ok;
                                }



                        -
                        Edité par IdrissNgou 31 mai 2019 à 22:06:17

                        • Partager sur Facebook
                        • Partager sur Twitter
                          5 juin 2019 à 16:48:36

                          On n'est dans le bordel depuis le début.

                          J'ai vu passé cette antiquité de DataReader, VIREZ MOI CETTE COCHONNERIE.

                          Depuis le départ, on n'est complètement hors de la cible finale, je pense.

                          Comme vous êtes déterminer à utiliser une procédure stockée pour insérer une nouvelle visite, il est LARGEMENT plus simple de ne pas fournir l'ID à la procédure mais qu'elle se démerde pour faire son taf sans.

                          Avantages évidents de cette approche, votre code client (en C#) est complètement indépendant de la structure interne de la base (que le champ ID de la table soit en auto incrément ou pas, c'est au concepteur de la procédure stockée de le gérer en fonction de CES contraintes (même si vous avez les 2 casquettes : dev appli. et dev. db)), et vous pouvez gérer de manière BEAUCOUP BEAUCOUP plus simple l'aspect transactionnel du bidule.

                          Dans le premier message, vous voulez appeler une procédure stockée (qui ne présente que des défauts, cf. ci-avant "ne pas fournir l'ID" à "ajouterVisite"). Mais vous le faite très mal. Ligne 9 vous tentez de lire le résultat de la requête avant d'appeler réellement, via un "ExecuteNonQuery" comme vous le fait maintenant pour "ajouterVisite". Lignes 10-17 rien à récupérer, cf.les remarques de @LilyKianii et le fait que les DataReader c'est CACA.

                          Le reste de la conversation ne sont que des élucubrations sur un usage complètement pété d'un truc qui ne sert qu'à ajouter des problèmes.

                          Si vous avez vraiment besoin de l'ID après l'appel d'AjouterVisite, fait en un paramètre en "output" et vous n'aurez qu'à lire sa valeur APRÈS avoir fait l'appel de procédure stockée.

                          P.S.: Virez-moi cette globale de mer.. !!!

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                          probleme dans une fonction

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown