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

C++ Discussion :

Problème pour récupérer les données d'un ResultSet (OCCI) - Débutant


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Juin 2006
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 69
    Points : 49
    Points
    49
    Par défaut Problème pour récupérer les données d'un ResultSet (OCCI) - Débutant
    Bonjour,

    Je suis actuellement en train de corriger un programmes en C++, et malheureusement pour moi, mes souvenirs concernant ce langage,
    sont très lointains. C'est pour cela, que je me tourne vers vous.

    Je rencontre un problème avec le gestion des resultSet avec OCCI.

    La requête doit retourner une dizaine de lignes, chacune composé d'un entier et d'un string.
    Pour chaque ligne récupéré on récupère les deux données afin de creer un objet. La champ string est convertit en char*.

    voici un bout de code simplifié :

    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
    18
    19
    20
    21
    22
    23
    24
    25
     
    Colonne *colonne;
    // ....
     
    Statement* requete = con->createStatement("//la requete");
     
    ResultSet* resultatRequete = requete->executeQuery();
     
    while (resultatRequete->next())
    {
      int numero = rs->getInt(1);
      string titre = rs->getString(2);
      colonne = new Colonne();
      colonne->setNumero(numero);
     
      int taille = titre.size()+1;
      char * buffer = new char[taille];
      strncpy(buffer,titre.c_str(),taille);	
     
      colonne->setTitre(buffer);   	
     
      // traitement
     
      delete [] buffer;
    }
    J'ai mis en place un fichier txt, dans lequel j'affiche l'ensemble des données récupérées via la requête. Je m'aperçois qu'il y a un seul passe dans la boucle après le programme plante.

    Il semblerait qu'il y ai un problème avec la récupération de l'élément String dans le resultSet.J'ai testé en ne récupérant pas celui-ci, et dans le fichier txt, j'ai bien les dix lignes qui s'affichent (avec juste les numéros). Le programme ne plante pas.

    J'utilisa Oracle 10.2, la version de compilateur est la 4.1.2 (Red hat 4.1.2).

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Comment fonctionne colonne->setTitre ? Pourquoi ne pas faire simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    while (resultatRequete->next())
    {
      int numero = rs->getInt(1);
      string titre = rs->getString(2);
      colonne = new Colonne();
      colonne->setNumero(numero);
      colonne->setTitre(titre.c_str());   	
    }
    Enfin, que devient colonne ? Et quels sont les traitements (il y a peut être un problème dans ceux-ci) ?

  3. #3
    Membre du Club
    Inscrit en
    Juin 2006
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 69
    Points : 49
    Points
    49
    Par défaut
    Bonjour,

    j'avais essayé de faire comme tu as indiqué mais ca plante également :

    voila la méthode qui plante :
    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
    18
    19
    20
    21
    22
    23
     
    bool Tableur::PeuplerColonne(bd *pBase,int idRegle)
    {
    Colonne *colonne;
    // ....
     
    Statement* requete = con->createStatement("//la requete");
     
    ResultSet* resultatRequete = requete->executeQuery();
     
    while (resultatRequete->next())
    {
      int numero = rs->getInt(1);
      string titre = rs->getString(2);
      colonne = new Colonne();
      colonne->setNumero(numero);
      colonne->setTitre(titre.c_str());
     
       addColonne(*colonne); //
      // traitement
     
    }
    }
    Toute les méthodes ou il y a des requêtes plantent avec l'utilisation de rs->getString().

    voila la classe le code de colonne.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class Colonne
    {	int numero;
    	char titre[SIZE_MAX_COL_XL];	
     
    	public:
    		Colonne(){};
    		virtual ~Colonne(){};
    		void setNumero(int num){numero=num;};
    		int getNumero(){return numero;};
    		void setTitre(char* ptitre){strcpy(titre,ptitre);};
    		char* getTitre(){return titre;};
    };
    le code de tableau.h
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    class Tableur
    {	int regleId;
    	int typeId; 
    	char separateur[SIZE_MAX_SEPARATEUR];
    	int deport;
    	vector<Colonne> listeColonne;
    	vector<Ligne> listeLigne;
     
    	public:
    		Tableur(){};
    		virtual ~Tableur(){};
    		int Peupler(bd *pBase,int pId);
    		bool PeuplerColonne(bd *pBase,int pIdRegle);
    		int PeuplerLigne(bd *pBase,int pIdRegle);
    		void setReglel(int id){regleId=id;};
    		int getRegle(){return regleId;};
    		void setTypeId(int id){typeId=id;};
    		int getTypeId(){return typeId;};
    		void setSeparateur(char* pseparateur){strcpy(separateur,pseparateur);};
    		char* getSeparateur(){return separateur;};
    		void setDeport(int dep){deport=dep;};
    		int getDeport(){return deport;};
    		void addColonne(Colonne col){listeColonne.push_back(col);};
    		ColonneXl getColonne(int i){ return listeColonne[i];};
    		void addLigne(Ligne ligne){listeLigne.push_back(ligne);};
    		Ligne getLigne(int i){ return listeLigne[i];};
    		vector<Ligne> getListeLigne(){return listeLigne;};
    		vector<Colonne> getListeColonne(){return listeColonne;};
    		void Affiche();
     
    };
    Merci pour ton aide

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Toujours dans la même veine, pourquoi utiliser des tableaux de char et non des std::string :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Colonne
    {	int numero;
    	std::string titre;	
    	
    	public:
    		Colonne(){};
    		virtual ~Colonne(){};
    		void setNumero(int num){numero=num;};
    		int getNumero()const{return numero;};
    		void setTitre(std::string const & titre_){titre = titre_;};
    		char const * getTitre() const {return titre.c_str();};
    // ou mieux :
    		std::string const & getTitre() const {return titre;};
    };
    idem pour separateur dans Tableur.

    On dirait que l'enregistrement est corrompu ? Est-ce que la colonne 2 est bien une string ? Est-ce que tu fais d'autres appels sur l'enregistrement/la base dans le while ?

  5. #5
    Membre du Club
    Inscrit en
    Juin 2006
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 69
    Points : 49
    Points
    49
    Par défaut
    En base la colonne 2 correspond à un varchar2, il semble que getString() soit la méthode appropriée pour ce type de donnée.

    J'ai regardé la doc de occi, je suis en train d'essayer d'utiliser l'objet Stream.
    (rs->getStream(2)). Normalement c'est réservé pour les grandes chaines d'après ce que j'ai compris, mais bon je test afin voir si ça fonctionne.

    Penses-tu que c'est correct d'utiliser getStream ? Si oui tu fais comment pour récupérer la valeur de la chaine ? je suis en train de tester et j'aimerais être sur que mon code est correct.

    En tout cas merci de prendre du temps, d'essayer de résoudre mon problème.

    Cordialement.

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Pour être franc, je ne connais pas OCCI. Mais les erreurs ont la fâcheuse tendance à se ressembler quelques soient les bibliothèques. Et la tienne, je vois 3 hypothèses :
    1/ Tu ne demandes pas le bon type de la colonne (d'où le getString ?).
    2/ Tu invalides ta requête car tu as un appel dans ton traitement vers la base qui l'invalide.
    3/ Tu provoques un écrasement mémoire (pile ou tas), d'où mes questions pour savoir si tu peux transformer tes char[] vers de std::string.

  7. #7
    Membre du Club
    Inscrit en
    Juin 2006
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 69
    Points : 49
    Points
    49
    Par défaut
    Bonjour,

    Il semblerait que le problème vienne de la méthode getString() (du ResulSet) car le programme plante juste quand je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    string test = rs->getString(2); 
    // sans affecté la chaine test au paramètre titre de l'objet Colonne
    On passe une seule fois dans la boucle et le programme plante.

    J'ai également essayé de ne récupérer seulement l'entier ( int test = rs->getInt(1) ) et le programme fonctionne correctement.

    Il semblerait que la méthode getString() pose des problèmes.

    Je suis un peu perdu. Je ne sais plus quoi faire comme test !!!

    Merci de ton aide.

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Il semblerait que ce soit un problème connu. La réponse oscille entre une différence de version de libstdc entre gcc et OCCI ou carrément un problème côté OCCI. Regarde du côté de la doc pour savoir si une version de gcc est explicitement spécifiée pour l'utilisation de ta version d'OCCI.
    Quelques info ici et ici.

Discussions similaires

  1. Problème pour lire les donnée d'une table externe
    Par mardoch dans le forum SQL*Loader
    Réponses: 6
    Dernier message: 17/07/2008, 16h41
  2. Problème pour récupérer les données d'un datafile
    Par KhaoOs dans le forum Import/Export
    Réponses: 5
    Dernier message: 23/10/2007, 11h24
  3. Réponses: 12
    Dernier message: 25/06/2006, 23h24
  4. Réponses: 1
    Dernier message: 07/06/2006, 18h56
  5. Réponses: 10
    Dernier message: 16/11/2005, 08h33

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