Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Qt] comment Ajouter des entrées dans une BDD SQLite

Sujet résolu
    6 mai 2010 à 12:36:41

    Bonjour,

    J'ai un petit souci concernant l'ajout de donnée dans ma base SQLite ! Comme je débute un peu en SQL et que j'utilise pour la première fois ce module de Qt, je ne sais pas si je fait les choses comme il faut ! :-°

    Pourrais-je avoir un petit coup de main s'il vous plait ?! ^^

    Voici mon code pour créer une table si elle n'existe pas :
    void Db2::creerTable(QString nom) // Fonction public : Crée une table dans la BDD
    {
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName("stock.db3");
    
        if(!db.open())
        {
            QMessageBox::critical(0, "Erreur","Connexion impossible :\n" + db.lastError().text());
            return;
        }
        else
        {
            int verif = 0;
            QStringList table = db.tables();
            for (int i = 0; i < table.count();i++)
            {
                if(table.at(i) == nom)
                {
                    QMessageBox::critical(0, "Stock","Ce nom existe déjà !");
                    db.close();
                    verif = 1;
                    return;
                }   
            }
            if (verif == 0)
            {
                QSqlQuery requeteCreate;
                QString requete;
    
                requete = "CREATE TABLE ";
                requete += nom;
                requete += " (id INTEGER PRIMARY KEY, ref VARCHAR(30), qte INTEGER)";
                requeteCreate.exec(requete);
                db.commit();
                db.close();
            }
        }
    }
    


    Pour cette première méthode, j'aimerais savoir si la requête SQL est correcte ? Est-il possible d'ajouter AUTO_INCREMENT à la clé primaire ? Si oui, de quelle manière ?

    Le code pour insérer des entrées les unes à la suite des autres :
    void Db2::ajouterEntree(QString nomTable,QString ref, int qte)
    {
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName("stock.db3");
    
        if(!db.open())
        {
            QMessageBox::critical(0, "Erreur","Connexion impossible :\n" + db.lastError().text());
            return;
        }
        else
        {
            int nbId;
            QSqlQuery nbEntrees;
            nbId = nbEntrees.size();
            nbId++;
    
            QSqlQuery requeteInsert;
            QString requete;
            requete = "INSERT INTO ";
            requete += nomTable;
            requete += " (id, ref, qte) VALUES (:id, :ref, :qte)";
    
            requeteInsert.prepare(requete);// Prépare la requête ci-dessus avant l'execution.
    
            requeteInsert.bindValue(":id",nbId);
            requeteInsert.bindValue(":ref",ref);// Place les valeurs aux emplacements de :ref et :qte ci-dessus.
            requeteInsert.bindValue(":qte",qte);
            requeteInsert.exec();
            db.close();
        }
    }
    


    C'est peut-être là que ça coince ! Si j'ajoute plusieurs entrées en faisant :

    ajouterEntree("table1","un truc", 150);

    Je n'ai que la première entrée d'affichée ! Peut-être cela vient-il de l'affichage ?!

    voici le code de l'affichage :
    void Db2::afficherTable(QString nomTable)
    {
        model = new QSqlTableModel(this);
        model->setTable(nomTable);
        model->setEditStrategy(QSqlTableModel::OnManualSubmit);
        model->setHeaderData(0, Qt::Horizontal, tr("ID"));
        model->setHeaderData(1, Qt::Horizontal, tr("Reférences"));
        model->setHeaderData(2, Qt::Horizontal, tr("Quantités"));
        model->select();
        model->database().transaction();
        if (model->submitAll())
        {
            model->database().commit();
        }
        else
        {
            model->database().rollback();
            QMessageBox::warning(this, "Erreur","Erreur: \n" + model->lastError().text());
        }
    
        ui->tableView->setModel(model);
    }
    


    Voilà, merci d'avance.
    • Partager sur Facebook
    • Partager sur Twitter
      6 mai 2010 à 13:03:44

      Comme le champ id est de type "INTEGER PRIMARY KEY", tu n'as pas à le préciser dans la requête INSERT, il est implicite et incrémenté automatiquement (en plus ta façon de le calculer faisait qu'il était tout le temps à 0, donc la requête échouait probablement).
      Donc:
      requete = "CREATE TABLE ";
      requete += nom;
      requete += " (ref, qte) VALUES (:ref, :qte)";
      

      Et il faut tester le résultat de la requếte:
      if (!requeteInsert.exec())
      {
         // afficher erreur
      }
      

      L'affichage ne va pas se mettre à jour tout seul après une requête d'insertion, mais je ne suis pas sûr de la bonne méthode pour y arriver.
      • Partager sur Facebook
      • Partager sur Twitter
        6 mai 2010 à 13:14:52

        Merci Alexisdm,

        ça fonctionne !

        Par contre c'est au niveau de l'affichage que ça ne va plus ! Lorsque je redémarre mon programme (sans les requêtes d'insertion) ça me met une erreur du type : Unabled to find table essai (essai est le nom que j'ai donné à la table pour faire les tests !).

        Je suis un peu perdu là :-°
        • Partager sur Facebook
        • Partager sur Twitter
          6 mai 2010 à 14:05:56

          La base n'a peut-être pas été ouverte quand tu ne fais pas de requête d'insertion avant.
          Tu devrais peut-être mettre db comme membre de ta classe Db2 et l'ouvrir la base de données une fois pour toutes dans le constructeur.

          Il faudrait aussi mettre le chemin absolu de la base:
          db.setDatabaseName(QApplication::applicationDirPath() + "/stock.db3");
          

          sinon il peut ne pas la trouver et créer une autre base de données vide automatiquement et silencieusement dans le répertoire courant.

          • Partager sur Facebook
          • Partager sur Twitter
            6 mai 2010 à 15:37:31

            Royal ! Merci du conseil. Tout fonctionne et ça simplifie grave le code des méthodes (en plus !).

            Donc, j'ai mon constructeur :
            Db2::Db2(QWidget *parent) :
                QWidget(parent),
                ui(new Ui::Db2)
            {
                ui->setupUi(this);
                db = QSqlDatabase::addDatabase("QSQLITE");
                db.setDatabaseName(QApplication::applicationDirPath() + "/stock.db3");
                if(!db.open())
                {
                    QMessageBox::critical(0, "Erreur","Connexion impossible :\n" + db.lastError().text());
                    return;
                }
            
            }
            


            Ensuite j'ai enlevé le code ci-dessus de mes autres méthodes et le tour est joué ! En tous cas ça fonctionne ! :p

            J'avais pas bien saisi le principe de la connexion à la base de donnée mais maintenant c'est plus clair !

            Un grand merci à toi alexisdm !
            • Partager sur Facebook
            • Partager sur Twitter
              20 juin 2010 à 14:29:13

              Salut

              Citation : sebmag

              int nbId;
                      QSqlQuery nbEntrees;
                      nbId = nbEntrees.size();
                      nbId++;
              
                      QSqlQuery requeteInsert;
                      QString requete;
                      requete = "INSERT INTO ";
                      requete += nomTable;
                      requete += " (id, ref, qte) VALUES (:id, :ref, :qte)";
              
                      requeteInsert.prepare(requete);// Prépare la requête ci-dessus avant l'execution.
              
                      requeteInsert.bindValue(":id",nbId);
              

              Si je puis me permettre :
              le coup du nbId n'est pas super car si tu supprime un entrée tu aura nbId qui sera déjà utilisé par une autre entrée (c'est clair ce que je dis ? o_O )
              Puisque ton Id a pour attribut "PRIMARY KEY " tu peux remplacer ta requête par
              requete += " (id, ref, qte) VALUES (NULL, :ref, :qte)";
              

              et SQLite va le remplir automatiquement en étant sur qu'il n'y aura pas de problème.

              Et il serait judicieux de vérifier les caractères contenus dans nomTable parce que si il y a des apostrophe ou des truc comme ça ça risque de planter (enfin j'en suis pas sur mais faut vérifier)
              • Partager sur Facebook
              • Partager sur Twitter
                20 septembre 2017 à 1:23:41

                j'ai presque le meme probleme mais mon code est bcp plus simple. j'aimerais entrer une suite de donnees avec une boucle mais

                a chaque fois que je lance mon programme seul le premier boucle s'affiche et s'arrete. 

                pourriez vous m'aider svp. cette fonction a ete appelee par un signal.

                 void Databse::messageup()
                    {
                      if (!open_data())
                          {
                      qWarning()<<"Echec de la connexion"<<mydb.lastError().text();
                          }
                
                     int balance;
                
                      QString nom,prenom;
                
                       open_data();
                       QSqlQuery query;
                      query.prepare("SELECT Name,Lastname FROM firstgrade order by Name,Lastname");
                
                      if(!query.exec())
                          {
                         QMessageBox::critical(this,tr("error::"),query.lastError().text());
                             }
                
                      else
                     {
                          while(query.next())
                          {
                               nom = query.value(0).toString();
                               prenom = query.value(1).toString();
                       balance=QInputDialog::getInt(this,"Saisie","Entrer la balance de : "+nom+" "+prenom);
                     query.prepare("UPDATE firstgrade set Balance=(:credit) where Name=(:name) and Lastname=(:last)");
                     query.bindValue(":credit",balance);
                     query.bindValue(":name",nom);
                     query.bindValue(":last",prenom);
                       
                 } // ending while
                
                          if(!query.exec())
                           {
                          QMessageBox::critical(this,tr("error::"),query.lastError().text());
                           }
                          else
                          {
                          QMessageBox::information(this,"Succes","Always");
                          }
                     } // ending else
                } // ending function



                -
                Edité par Dydy02 20 septembre 2017 à 1:33:18

                • Partager sur Facebook
                • Partager sur Twitter

                [Qt] comment Ajouter des entrées dans une BDD SQLite

                × 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