Problème API mysql: fonction mysql_fetch_row [Résolu]

Moebiius - 1 sept. 2015 à 17:12 - Dernière réponse : cptpingu 3766 Messages postés dimanche 12 décembre 2004Date d'inscriptionModérateurStatut 1 décembre 2017 Dernière intervention
- 1 sept. 2015 à 18:34
Bonjour,
J'utilise l'API mysql dans mon programme en C++, et j'ai un problème avec la fonction mysql_fetch_row: en effet, il m'est impossible de l'appeler deux fois de suite, ce qui est plutôt problématique puisque j'ai besoin de faire de nombreux appels à ma base de données et d'en récupérer pas mal de valeurs que je traite ensuite.
Voici un exemple de code qui ne fonctionne pas:

int main()
{
int variable1,variable2;
MYSQL *database;
database=mysql_init(NULL);
mysql_options(database, MYSQL_READ_DEFAULT_GROUP, "option");
if(mysql_real_connect(database, "localhost", "root" , "password", "database", 0, NULL, 0))
{
cout << "Connexion to database succeed" << endl;
MYSQL_RES *result=NULL;
MYSQL_ROW row=NULL;
mysql_query(database, "SELECT field1 FROM table1 WHERE id=1");
result=mysql_use_result(database);
row=mysql_fetch_row(result);
variable1=atoi(row[0]);
mysql_free_result(result);

mysql_query(database, "SELECT field1 FROM table2 WHERE id=1");
result=mysql_use_result(database);
row=mysql_fetch_row(result);
variable2=atoi(row[0]);
mysql_free_result(result);
}
else
{
cout << "ERROR: DATABASE CONNEXION" << endl;
}

mysql_close(database);
return 0;
}


Quand j'utilise une seule fois mysql_fetch_row (en n'allouant donc de valeur qu'à variable1), tout fonctionne bien. Mais dès que j'utilise cette fonction une seconde fois, le programme plante. De plus, j'ai essayé de créer des variables MYSQL_RES et MYSQL_ROW différentes (*result2 et row2) afin de stocker le résultat de la seconde requête, mais toujours sans succès.
Merci d'avance pour votre aide!
Afficher la suite 

2 réponses

Répondre au sujet
cptpingu 3766 Messages postés dimanche 12 décembre 2004Date d'inscriptionModérateurStatut 1 décembre 2017 Dernière intervention - Modifié par cptpingu le 1/09/2015 à 17:33
0
Utile
Bonjour.

Essaie d'afficher plus de détails au niveau des erreurs.
Voici ce que j'utilise chez moi (et qui fonctionne bien):
int executeQuery(MYSQL* mysql, const std::string& query)
{
    std::clog << mysql->host << ", query: " << query << std::endl;
    int retval;

    query:
    retval = mysql_real_query(mysql, query.c_str(), query.length());

    switch (mysql_errno(mysql))
    {
    case CR_COMMANDS_OUT_OF_SYNC:
    {
      std::cerr << "host: " << mysql->host << ", CR_COMMANDS_OUT_OF_SYNC !!!" << std::endl;
      assert(false && "you call mysql_real_query, mysql_{store,use,free,next}_result in a bad order. Fix it !");
      MYSQL_RES* result = mysql_use_result(mysql);
      mysql_free_result(result);
      goto query;
    }

    case 0:
      break;

    default:
      std:cerr << "retval: " << retval << ", errno: " << mysql_errno(mysql)
                 << ", " << mysql_error(mysql) << std::endl
                 << "host: " << mysql->host << ", query: " << query << std::endl;
    }

    return retval;
}

int main()
{
  MYSQL* mysql= mysql_init(0);
  assert(mysql);
  mysql_options(database, MYSQL_READ_DEFAULT_GROUP, "option");
  if (!mysql_real_connect(database, "localhost", "root" , "password", "database", 0, 0, 0))
  {
     std::cerr << "Connection error!" << std::endl;
     return 1;
  }

  int retval = executeQuery(mysql, "SELECT field1 FROM table1 WHERE id=1");

  if (retval)
  {
      std::cerr << "Query failed " << mysql_error(mysql) << std::endl;
      return 2;
  }

    MYSQL_RES* result = mysql_store_result(mysql);
    if (!result)
    {
      std::cerr << "Query can't be retrieved " << mysql_error(mysql) << std::endl;
      return 3;
    }

    MYSQL_ROW row;
    while ((row = mysql_fetch_row(result)))
    {
       int variable = atoi(row[0]);
       std::cout << variable << std::endl;
    }

     mysql_free_result(result);
     mysql_close(database);

     return 0;
}


Attention, j'ai écrit ce code sans le tester. Le principe est bon, mais il peut y avoir des petites erreurs de syntaxe.


Améliorer votre expérience CodeS-SourceS avec ce plugin:
http://codes-sources.commentcamarche.net/forum/affich-10000111-plugin-better-cs-2#cptpingu-signature
Commenter la réponse de cptpingu
cptpingu 3766 Messages postés dimanche 12 décembre 2004Date d'inscriptionModérateurStatut 1 décembre 2017 Dernière intervention - Modifié par cptpingu le 1/09/2015 à 18:38
0
Utile
Je viens de faire un exemple propre chez moi, que j'ai testé. Je n'ai aucun souci à lancer plusieurs requêtes sur des tables différentes.

Mon code (il te faudra adapter les requêtes et informations de connexion):
#include <iostream>
#include <cassert>
#include <mysql/mysql.h>
#include <mysql/errmsg.h>
#include <cstdlib>

int executeQuery(MYSQL* mysql, const std::string& query)
{
  std::clog << mysql->host << ", query: " << query << std::endl;
  int retval;

 query:
  retval = mysql_real_query(mysql, query.c_str(), query.length());

  switch (mysql_errno(mysql))
  {
    case CR_COMMANDS_OUT_OF_SYNC:
      {
         std::cerr << "host: " << mysql->host << ", CR_COMMANDS_OUT_OF_SYNC !!!" << std::endl;
         assert(false && "you call mysql_real_query, mysql_{store,use,free,next}_result in a bad order. Fix it !");
         MYSQL_RES* result = mysql_use_result(mysql);
         mysql_free_result(result);
         goto query;
      }

    case 0:
      break;

    default:
      std::cerr << "retval: " << retval << ", errno: " << mysql_errno(mysql)
                << ", " << mysql_error(mysql) << std::endl
                << "host: " << mysql->host << ", query: " << query << std::endl;
  }

  return retval;
}

int launchQuery(MYSQL* mysql, const std::string& query)
{
  int retval = executeQuery(mysql, query);

  if (retval)
  {
    std::cerr << "Query failed " << mysql_error(mysql) << std::endl;
    return 2;
  }

  MYSQL_RES* result = mysql_store_result(mysql);
  if (!result)
  {
    std::cerr << "Query can't be retrieved " << mysql_error(mysql) << std::endl;
    return 3;
  }

  MYSQL_ROW row;
  while ((row = mysql_fetch_row(result)))
  {
    int variable = atoi(row[0]);
    std::cout << variable << std::endl;
  }

  mysql_free_result(result);
  return 0;
}

int main()
{
  MYSQL* mysql= mysql_init(0);
  assert(mysql);
  mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "option");
  if (!mysql_real_connect(mysql, "localhost", "user" , "pass", "db", 0, 0, 0))
  {
    std::cerr << "Connection error!" << std::endl;
    return 1;
  }

  launchQuery(mysql, "SELECT ID FROM TABLE1 limit 10;");
  launchQuery(mysql, "SELECT ID FROM TABLE2 limit 10;");

  mysql_close(mysql);

  return 0;
}




Améliorer votre expérience CodeS-SourceS avec ce plugin:
http://codes-sources.commentcamarche.net/forum/affich-10000111-plugin-better-cs-2#cptpingu-signature
Commenter la réponse de cptpingu

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.