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 :

Manipuler les bases de données à l'aide de l'API ODBC en C++


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2015
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2015
    Messages : 39
    Points : 27
    Points
    27
    Par défaut Manipuler les bases de données à l'aide de l'API ODBC en C++
    Bonjour, je travail sur code qui essaie de manipuler des bases de données en mode ODBC. je teste mon code s'il est connecté à ma table Employe(IdEmploye,Nom,Prenom,Raison Sociale,Matricule,IdPresAbs) en plus d'autre étape expliquer en commentaire dans le code.
    le problème qui se pose c'est quand j'appelle la fonction qui ajoute des champs à ma base de donnée la fonction la ligne 35 du .cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ajouterRecord(char*,int)
    j'ai essayé de l'écrire en fonction mais ceci ne marche pas et je ne sais pas pourquoi pourtant le compilateur (Visual Studio) n'indique pas d'erreur???
    le main.cpp
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    #define WINVER 0x0A00
    #include <iostream>
    #include <afxdb.h>
    #include "RecordsetE.h"
    using namespace std;
     
    int main(){
    			//objet database
    	CDatabase dbGT_1_ODBC;		
    			//source ODBC
    	CString sDSN ("TestGTODBC");	
    			//trouver connecter la base de donnee
    	dbGT_1_ODBC.Open(sDSN);		
    	if(dbGT_1_ODBC.IsOpen()){
    		cout<<"-- DB trouvee et connectee! --" << endl;
    	}else{cout << "-- DB pas trouvee ou echec de connexion! --" << endl;}
    			//definir les objets necessaires
    	CRecordsetE rsEmploye(&dbGT_1_ODBC);
    	CString sSQL("SELECT* FROM employe");
    			// ---- ouvrir et rechercher les enregistrements ----
    	rsEmploye.m_strSort=_T("Nom");		//tri sur les noms
    	rsEmploye.Open(CRecordset::dynaset,sSQL);
    	if(!(rsEmploye.IsOpen() && rsEmploye.CanAppend())){
    		cout<<"-- Recordset non connecte !"<<endl;}
    			//ajouter un record à la table
    	cout<<"voulez vous ajouter de nouveaux employes si oui cliquer 'O' si non cliquer 'N' ";
    	char c='O';
    	cin>>c;
    	if(c=='O'){
    		char* newEmploye=NULL;
    		int element=0;
    	cout<<"combien d'employe voulez vous entrer :";
    	cin>>element;
    	cout<<endl;
    	rsEmploye.ajouterRecord(newEmploye,element);
    	}
    			//lister tout les records de la table
    	rsEmploye.MoveFirst();		// aller au premier record de la table
    	//boucle sur les enregistrements//IsEOF retourne 0 apres le dernier enregistrement
    	while(!rsEmploye.IsEOF()){
    				// récuperer les valeurs des champs
    				// afficher les valeurs des champs
    		cout<<rsEmploye.m_IdEmploye<<" - "<<rsEmploye.m_Nom<<" - "<<rsEmploye.m_Prenom;
    		cout<<" - "<<rsEmploye.m_Raison_Sociale<<" - "<<rsEmploye.m_Matricule<<endl;
    				// passer au record suivant
    		rsEmploye.MoveNext();
    	}
    			// fermer le recordset
    	rsEmploye.Close();
    			//fermer (deconnecter) la base de donnee
    	dbGT_1_ODBC.Close();		
    	if(dbGT_1_ODBC.IsOpen()){
    		cout << "-- DB echec de fermeture! --" << endl;
    	}else{cout<<"-- DB deconnectee et fermee"<<endl;}
     
    	return 0;
    }
    le fichier .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
    #pragma once
    #include <afxdb.h>
    using namespace std;
     
    class CRecordsetE: public CRecordset
    {
    public:
    	// data membres correspondant aux champs de la table
    	long m_IdEmploye;
    	CStringA m_Nom;
    	CStringA m_Prenom;
    	CStringA m_Raison_Sociale;
    	long m_Matricule;
    	CString m_Telephone;
    	long m_IdPresAbs;
    public:
    	CRecordsetE(CDatabase* );
    	virtual ~CRecordsetE();
    	// fonction de mappage
    	virtual void DoFieldExchange(CFieldExchange*);
    	void ajouterRecord(char*,int);
    };
    et le fichier où existe ma fonction le .cpp :
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    #include "RecordsetE.h"
    #include <afxdb.h>
    #include <iostream>
    using namespace std;
     
    CRecordsetE::CRecordsetE(CDatabase* pDatabase=NULL)
    	:CRecordset(pDatabase)
    {
    	m_IdEmploye=0;
    	m_Nom=_T("");
    	m_Prenom=_T("");
    	m_Raison_Sociale=_T("");
    	m_Matricule=0;
    	m_Telephone=_T("");
    	m_IdPresAbs=0;
    	m_nFields=7;		//nombre de champs
    	m_nDefaultType=dynaset;		//mode d'ouverture par default
    }
     
    CRecordsetE::~CRecordsetE(void)
    {
    }
     
    void CRecordsetE::DoFieldExchange(CFieldExchange* pFX)
    {
    	//champs à mapper
    	pFX->SetFieldType(CFieldExchange::outputColumn);	
    	RFX_Long(pFX,_T("[IdEmploye]"),m_IdEmploye);
    	RFX_Text(pFX,_T("[Nom]"),m_Nom);
    	RFX_Text(pFX,_T("[Prenom]"),m_Prenom);
    	RFX_Text(pFX,_T("[Raison Sociale]"),m_Raison_Sociale);
    	RFX_Long(pFX,_T("[Matricule]"),m_Matricule);
    	RFX_Text(pFX,_T("[Telephone]"),m_Telephone);
    	RFX_Long(pFX,_T("[IdPresAbs]"),m_IdPresAbs);
    }
     
    void CRecordsetE::ajouterRecord(char* newEmploye,int element)
    {
    	newEmploye=new char[element];
    	newEmploye[0]='0';
    	for(int j=0;j<element;j++){
    		cout<<"entrer un nom pour l'employe "<<j++<<" :";
    		cin>>newEmploye[j];
    		cout<<endl;
    	}
    	for(int i=0;i<element;i++){
    	this->AddNew();
    	this->m_IdEmploye=6+i;
    	this->m_Nom=newEmploye[i];
    	this->m_Matricule=13001+i;
    	this->Update();
    	this->Requery();
    	}
    }
    merci !

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 073
    Points : 12 119
    Points
    12 119
    Par défaut
    j'ai essayé de l'écrire en fonction mais ceci ne marche pas et je ne sais pas pourquoi pourtant le compilateur (Visual Studio) n'indique pas d'erreur???
    Oui, est c'est quoi le problème ?
    Moi, je vois que vous utilisez ces antiquités que sont les CRecordset des MFC sans faire gaffe le moins du monde au typage juste bon à faire du vieux C et une gestion de la mémoire complètement au fraise (pas de new ni de delete dans du code C++ moderne).

    Ligne 39 de votre cpp, vous créez un tableau de caractères, pas un tableau de tableau de caractère.
    "newEmploye[x]" doit être une chaine de caractères pas un caractère.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2015
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2015
    Messages : 39
    Points : 27
    Points
    27
    Par défaut
    Citation Envoyé par bacelar Voir le message
    Oui, est c'est quoi le problème ?
    Moi, je vois que vous utilisez ces antiquités que sont les CRecordset des MFC sans faire gaffe le moins du monde au typage juste bon à faire du vieux C et une gestion de la mémoire complètement au fraise (pas de new ni de delete dans du code C++ moderne).
    D'abord Merci d'avoir pris le temps de me répondre.
    oui je suis en train de tester les différentes mode de connexion avec ma base de donnée j'ai commencé par l'ODBC. Il n'y a pas d'erreur mais le code n'affiche pas de résultat car il doit m'afficher ma table.

    PS: pouvez vous me conseiller d'autre mode de connexion autre que ODBC ?

    Citation Envoyé par bacelar Voir le message
    Ligne 39 de votre cpp, vous créez un tableau de caractères, pas un tableau de tableau de caractère.
    "newEmploye[x]" doit être une chaine de caractères pas un caractère.
    justement parce que dans la ligne 49
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this->m_Nom=newEmploye[i];
    mon attribut est de type CStringA alors de newEmploye[i] ne peut pas être un string car il y a conflit de conversion

  4. #4
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Tu n'utilises pas ODBC en natif, mais la surcouche MFC.
    Certes c'est une antiquité, mais elle est sans doute éprouvée.
    Perso je ne l'ai jamais utilisée.

    J'utilise ma propre surcouche C++ au dessus de l'api native ODBC, ça me permet d'éviter les CString et autre classe MFC au profit des std::string et du C++ standard en général.
    Mais j'ai bcp utilisé MSADO. C'est plus facile je trouve, sécurisé et éprouvé, mais moins performant.

    Quant à ton code, je rejoins bacelar.
    Tu sembles mélanger chaîne de caractère et caractère.
    Le nom de tes employés n'aura qu'un seul caractère dans la db.
    De plus, il y a moyen d'éviter le new comme tu le fais (et pour lequel je ne vois pas de delete correspondant).

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2015
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2015
    Messages : 39
    Points : 27
    Points
    27
    Par défaut
    Citation Envoyé par camboui Voir le message
    J'utilise ma propre surcouche C++ au dessus de l'api native ODBC, ça me permet d'éviter les CString et autre classe MFC au profit des std::string et du C++ standard en général.
    Qu'est ce que tu veux dire par "native ODBC" ? pour moi j'utilise ODBC avec ce qu'il offre comme classe et architecture. y-t-il des pistes où je peux trouver comment developper ma propre surcouche?
    Citation Envoyé par camboui Voir le message
    Quant à ton code, je rejoins bacelar.
    Tu sembles mélanger chaîne de caractère et caractère.
    Le nom de tes employés n'aura qu'un seul caractère dans la db.
    De plus, il y a moyen d'éviter le new comme tu le fais (et pour lequel je ne vois pas de delete correspondant).
    oui j'ai corrigé le problème quand à ce point j'ai utilisé des char**. car le problème qu'il y avait c'est que je dois affecter des char à des objets de type CString, cette dernière n'admet pas de std::string.
    merci !

  6. #6
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Citation Envoyé par monsrhf Voir le message
    Qu'est ce que tu veux dire par "native ODBC" ?
    https://docs.microsoft.com/en-us/sql...-api-reference
    Citation Envoyé par monsrhf Voir le message
    ... pour moi j'utilise ODBC avec ce qu'il offre comme classe et architecture. y-a-t-il des pistes où je peux trouver comment développer ma propre surcouche?
    ODBC est écrite en C. Il faut la maitriser un minimum, ainsi que le C++...

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 073
    Points : 12 119
    Points
    12 119
    Par défaut
    PS: pouvez vous me conseiller d'autre mode de connexion autre que ODBC ?
    Des Middleware d'interconnexion, il y en a littéralement des centaines.

    Il faut spécifier un peu les besoins pour qu'on puissent vous en présenter une sélection "pertinente".

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2015
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2015
    Messages : 39
    Points : 27
    Points
    27
    Par défaut
    Citation Envoyé par bacelar Voir le message
    Des Middleware d'interconnexion, il y en a littéralement des centaines.

    Il faut spécifier un peu les besoins pour qu'on puissent vous en présenter une sélection "pertinente".
    Je travail sur un mini projet de gestion des temps en open source, je veux une bibliothèque ou une API qui simplifie la connexion à la base de donnée et qui va me permettre de développer mon projet en open source.

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 073
    Points : 12 119
    Points
    12 119
    Par défaut
    Je travail sur un mini projet de gestion des temps en open source, je veux une bibliothèque ou une API qui simplifie la connexion à la base de donnée et qui va me permettre de développer mon projet en open source.
    C'est pas super discriminant comme description.
    Mais ODBC est tellement vieux et bas niveau que c'est un peu près le pire choix.
    "open source" + MFC, c'est un peu une oxymore.
    Un outillage moderne pour l'accès base de données est à base d'ORM (Object Relational Mapper), ou peut-être des trucs encore plus récents, mais en aucun cas cette antiquité d'ODBC.

Discussions similaires

  1. Manipuler une base de donnée à l'aide des Codes Pascal
    Par batonnier 5 dans le forum Bases de données
    Réponses: 4
    Dernier message: 31/08/2010, 12h44
  2. Réponses: 3
    Dernier message: 17/05/2010, 14h47
  3. Aide sur les bases de données
    Par weedox dans le forum Décisions SGBD
    Réponses: 4
    Dernier message: 24/10/2008, 14h36
  4. Réponses: 4
    Dernier message: 03/01/2007, 21h56

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