Problème API mysql: fonction mysql_fetch_row

Résolu
Moebiius - 1 sept. 2015 à 17:12
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 - 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!

2 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié par cptpingu le 1/09/2015 à 17:33
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
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié par cptpingu le 1/09/2015 à 18:38
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
0
Rejoignez-nous