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 :

[c++] classe et requete SQL ?


Sujet :

C++

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 412
    Par défaut [c++] classe et requete SQL ?
    Hello

    je suis quelque peux coincé.je vai essaye d'être explicite mai c est pas évident
    j'ai donc une classe cSQL ,qui utilise une base de type sqlite

    Avec une méthode qui a pour but d'utiliser la méthode public de la classe
    sous cette forme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void setInsert(const std::string & Valeur,const std::string & Table, const std::string & NameCol)		;
    c'est donc par la suite facilment ecessible depuis l'exterieur de la classe d'inserer des donnée a première vue. le probleme viens évidament de l'interieur de la methode:

    Et c'est la que sa coince car je prépare la requête avec la fonction en C de sqlite. http://www.sqlite.com/c3ref/prepare.html

    Donc sa aurait cette forme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    //std::string exe="INSERT INTO MATABLE (ID,NOM)VALUES (?,?)"
    _RqInsertData= "INSERT INTO "+ Table + "(" + NameCol + ")VALUES (?)";
    Le souci est de savoir comment je peux varier les appelles si les requêtes changes.
    Par exemple à cause d 'une requête qui concerne non plus 1 table mai 2. Car un champs serai soumis aux contrainte (clef champs étrangère)
    et donc les données doive être insérée en même temps dans une ou deux table.
    Et la sa coince car
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _RqInsertData= "INSERT INTO "+ Table + "(" + NameCol + ")VALUES (?)";
    n'est plus possible , seul moyen est de passer la requette aux complet dans les argument avec les valeur. ce qui rend la methode peux utile et oblige a en faire une pour chaque posibiliter ...

    l'idée serai donc aux final que la methode puisse être plus facile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void setInsert(const std::string & Valeur,const std::string & ValeurIDtable,const std::string & Table,const std::string & IDTable, const std::string & NameCol,const std::string & IDNameCol)		;
    sa permet donc d'affecter celons l'id qui fera référence a la bonne table et les valeur qui lui sont liée ...

    j'espère avoirs été compris, car c'est loin d'être facile à expliquer.

    Merci d'avance

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    pourquoi ne pas utiliser une 2° fonction (ou uniquement cette seconde fonction) qui prendrait en paramètre un tableau de std::string qui sont les tables où réaliser l'insertion ?
    Ensuite formater la requête correctement avec les entrées de ce tableau.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Pourquoi ne pas construire la requêtre sql de manière plus... lisible ?

    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
     
    class sqlinsert
    {
    public:
      sqlinsert& value(const sqlfield& f, const sqlvalue& v);
      sqlresult execute();
    };
     
    class sqlselfrom
    {
    public:
      sqlselfrom& where(const sqlcond& cond1);
      /* ... */
      sqlresult execute();
    };
     
    class sqlselect
    {
    public:
      sqlselfrom& from(const sqltable& tbl) const;
      sqlselfrom& from(const sqltable& tbl1, const sqltable& tbl2) const;
      /* ... */
    };
     
    class sqldb
    {
    public:
      sqlinsert insert_into(const sqltable& tbl) const;
      sqlinsert insert_into(const sqltable& tbl1, const sqltable& tbl2) const;
      /* ... */
      sqlselect select() const; /* == SELECT * */
      sqlselect select(const sqlfield& f) const;
      sqlselect select(const sqlfield& f1, const sqlfield& f2) const;
      /* ... */
    };
     
    // ------------------- utilisation ---------------------
    void function(const sqldb& db)
    {
      sqltable tbl1("table1");
      sqltable tbl2("table2");
      sqlfield field1 = make_field<std::string>(tbl1, "string_field");
      sqlfield field2 = make_field<int>(tbl1, "integer_field");
     
      sqlresult result;
     
      result = db.insert_into(tbl1)
        .value(field1, "value1")
        .value(field2, 100)
        .execute();
     
      result = db.select()
        .from(tbl1, tbl2)
        .where(make_equal_cond("table1.string_field", "table2.string_field"))
        .execute();
    }
    Ca serait bien évidemment plus propre avec des variadic templates et des lambda, mais bon, on fait ce qu'on peut

    Bien évidemment, il y a un peu plus de boulot que ce que je viens de noter, avec les jointure et toutes les petites choses amusantes qu'on peut faire avec une requête.

    A noter aussi que boost::proto doit pouvoir aider à fabriquer un dsel qui permettra presque d'écrire des requète SQL directement dans le code C++. Ca devrait pouvoir se faire. Après tout, le seul besoin est de construire une chaine de caractère qui puisse être interprété par le moteur SQL sous-jacent.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 412
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Bonjour,

    pourquoi ne pas utiliser une 2° fonction (ou uniquement cette seconde fonction) qui prendrait en paramètre un tableau de std::string qui sont les tables où réaliser l'insertion ?
    Ensuite formater la requête correctement avec les entrées de ce tableau.
    j'ai déjà essayer , il en ressort que sa deviens ingerable car tu t'en sort plus, il est préférable de passe par un objet qui parle de lui même, oui bon hum.
    je vai essayer d'expliquer

    si tu prend un tableau
    sa va contenir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tabSQL=1.- Rq1
    2.- Rq2
    3.-Rq3
    Et après pour retrouver les valeur tu te prend la tête à boucler dessus pour trouver la bonne entrée, vu que les tables et les colonnes (7 tables) pour env. (18 valeur) je te laisse imaginer le bordel pour si retrouver avec un tableaux

    alors que si tu leur donne un nom direct ,tu obtiens un typage fort (ce que je ne maîtrise pas encore très bien )
    en très gros si sa concerne les accès disques.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    std:: string fichier 
    fichier.scanDisque=rq
    fichier.statFile=rq2
    Ainsi tu as accès directement a la bonne valeur et la variable à un nom qui parle pourvu qu'elle soie bien choisie.

    Mai le souci reste du coter de sqlite et du problème citer plus haut, formaté la string (la requête) + la valeur
    peux faire planter le soft ou le rendre instables. c'est donc pas la solution idéal mai aux pire sa reste possible

    merci de m'avoir lu

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 412
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    Pourquoi ne pas construire la requêtre sql de manière plus... lisible ?

    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
     
    class sqlinsert
    {
    public:
      sqlinsert& value(const sqlfield& f, const sqlvalue& v);
      sqlresult execute();
    };
     
    class sqlselfrom
    {
    public:
      sqlselfrom& where(const sqlcond& cond1);
      /* ... */
      sqlresult execute();
    };
     
    class sqlselect
    {
    public:
      sqlselfrom& from(const sqltable& tbl) const;
      sqlselfrom& from(const sqltable& tbl1, const sqltable& tbl2) const;
      /* ... */
    };
     
    class sqldb
    {
    public:
      sqlinsert insert_into(const sqltable& tbl) const;
      sqlinsert insert_into(const sqltable& tbl1, const sqltable& tbl2) const;
      /* ... */
      sqlselect select() const; /* == SELECT * */
      sqlselect select(const sqlfield& f) const;
      sqlselect select(const sqlfield& f1, const sqlfield& f2) const;
      /* ... */
    };
     
    // ------------------- utilisation ---------------------
    void function(const sqldb& db)
    {
      sqltable tbl1("table1");
      sqltable tbl2("table2");
      sqlfield field1 = make_field<std::string>(tbl1, "string_field");
      sqlfield field2 = make_field<int>(tbl1, "integer_field");
     
      sqlresult result;
     
      result = db.insert_into(tbl1)
        .value(field1, "value1")
        .value(field2, 100)
        .execute();
     
      result = db.select()
        .from(tbl1, tbl2)
        .where(make_equal_cond("table1.string_field", "table2.string_field"))
        .execute();
    }
    Ca serait bien évidemment plus propre avec des variadic templates et des lambda, mais bon, on fait ce qu'on peut

    Bien évidemment, il y a un peu plus de boulot que ce que je viens de noter, avec les jointure et toutes les petites choses amusantes qu'on peut faire avec une requête.

    A noter aussi que boost::proto doit pouvoir aider à fabriquer un dsel qui permettra presque d'écrire des requète SQL directement dans le code C++. Ca devrait pouvoir se faire. Après tout, le seul besoin est de construire une chaine de caractère qui puisse être interprété par le moteur SQL sous-jacent.
    Merci pour ta réponse.

    Voila les question en fonction de ce que j'ai compris (c'est a dire pas grands chose)
    que cherche tu a faire exactement avec:

    sqlfield field1 = make_field<std::string>(tbl1, "string_field");

    si j'ai bien compris:
    obtenir un objet complet qui est le résulta de la requête qui viens d'être construite par les classe && fonction ?
    ensuite tu les envoiyes a la lib sqlite qui fait le boulôt ?

    ce qui me derenge c'est ton make_field<std::string>
    tu passes un tableaux quelque part ???

    Merci pour l'aide apportée et les pistes

    pour ce qui est de boost on oublie, car j'aime pas être depandant d'autre libraire sauf quand sa devient indispensable. car sa me force a apprendre les base meme si sa ré-invente la roue

  6. #6
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    J'ai passé certains détails sous silence. Ceci dit, la notation xxx<T> n'a pas grand chose à voir avec les tableaux, ni même les vecteurs. C'est la notation utilisée pour instancier une fonction ou un type générique (les templates).

    Dans l'idée de ce design, sqlfield est une classe polymorphique qui possède un sous-type template sqlfield_spec<T>, typedefé en sqlfield_int, sqlfield_string, ...

    La fonction make_field<T>(const sqltable& table, const std::string& name) permet de créer un objet sqlfield_spec<T> liant la table tbl au nom de colonne name - c'est tout. On peut tout à fait imaginer s'en passer, ça n'est pas critique du tout. sqlfield peut être une classe non polymorphique, avec deux méthode template set_value<T> et get_value<T> se basant sur un variant ou quelque chose dans le style (c'est l'approche de Qt).

    Maintenant, et très honnètement, j'ai écrit tout ça sans trop réfléchir pendant que j'attendais la fin d'une compilation. Il faudrait que je pose ça dans un coin, que je regarde plus longuement, histoire de fournir un service correct. J'essaierais de faire ça dans les jours qui viennent, parce que ça me parait sympathique - dans l'idée.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 412
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    J'ai passé certains détails sous silence. Ceci dit, la notation xxx<T> n'a pas grand chose à voir avec les tableaux, ni même les vecteurs. C'est la notation utilisée pour instancier une fonction ou un type générique (les templates).

    Dans l'idée de ce design, sqlfield est une classe polymorphique qui possède un sous-type template sqlfield_spec<T>, typedefé en sqlfield_int, sqlfield_string, ...

    La fonction make_field<T>(const sqltable& table, const std::string& name) permet de créer un objet sqlfield_spec<T> liant la table tbl au nom de colonne name - c'est tout. On peut tout à fait imaginer s'en passer, ça n'est pas critique du tout. sqlfield peut être une classe non polymorphique, avec deux méthode template set_value<T> et get_value<T> se basant sur un variant ou quelque chose dans le style (c'est l'approche de Qt).

    Maintenant, et très honnètement, j'ai écrit tout ça sans trop réfléchir pendant que j'attendais la fin d'une compilation. Il faudrait que je pose ça dans un coin, que je regarde plus longuement, histoire de fournir un service correct. J'essaierais de faire ça dans les jours qui viennent, parce que ça me parait sympathique - dans l'idée.
    Si tu veux on peux le faire ensemble, pour l'instant je vai faire une classe simple avec du "static pour chaque requette .... pas génial mai bon sa permet déja d'avancer en attendant de mieux comprendre, j'ai une autre livre a lire (le 3eme en c++...) avec des astuce dedans j'arrive justement dans le domaine des template sur les classes je pense que sa va servir

Discussions similaires

  1. php POO question sur les class et requetes SQL
    Par craz00 dans le forum Langage
    Réponses: 3
    Dernier message: 28/02/2014, 00h25
  2. Réponses: 4
    Dernier message: 02/03/2013, 22h18
  3. Requete SQL complexe avec DBIx::Class::Resultset
    Par pierrot_de_la_pampa dans le forum SGBD
    Réponses: 0
    Dernier message: 23/01/2010, 18h11
  4. requete SQL avec groupement et ventilation par classe
    Par peio89 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 27/10/2006, 08h49
  5. Resultat requete SQL
    Par PierDIDI dans le forum Bases de données
    Réponses: 2
    Dernier message: 23/07/2002, 13h43

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