MySQL en C

 

 

Sous Debian, Raspbian, ...

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install libmysqlclient-dev

AttentionSur les dernières versions du système, la librairie libmysqlclient-dev n'est plus disponible. En effet, MariaDB remplace MySQL. Une nouvelle librairie est donc disponible compatible avec la précédente.

D'où l'installation de libmariadbclient-dev:

apt-get install libmariadbclient-dev

Sous Mageia

Utilisez le centre de contrôle de Mageia (sous Outils, outils système) et installez un paquet lib64maria de dev contenant les headers (lib64mariadb-devel...).

Note MySQL étant repris par Oracle, un clone (fork) de MySQL a été créé et nommé MariaDB. Il fonctionne exactement comme MySQL.

 

Include

#include <mysql/mysql.h>

 

Connexion base MySQL

La base existant déjà (via phpMySQL par exemple), vous pouvez vous y connecter:

mysql_init(&mysql) permet de réinitialiser la structure mysql.

mysql_options permet de déclarer les options

mysql_real_connect permet de faire la connexion à la base. Si cette fonction retourne NULL, la connexion a échoué.

MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)

En paramètres:

  • Pointeur vers structure MYSQL.
  • Un nom de domaine ou localhost.
  • Identifiant de connexion que vous utilisez par exemple avec PhpMyAdmin.
  • Mot de passe de l'identifiant
  • Nom de la base de données.
  • Port, vous pouvez mettre 0.
  • Socket à utiliser ou NULL.
  • Flag ou 0.
    • CLIENT_FOUND_ROWS

Note Une connexion à distance chez certains hébergeurs n'est pas possible (raison de sécurité de la base et de ses données !). Le port étant tout simplement bloqué !

Déconnexion base MySQL

mysql_close(MYSQL *mysql);

Simple non ?

 

Passer des requètes SQL

mysql_query(MYSQL *mysql, const char *query);

En entrée:

Votre structure MYSQL

query lui contenant la requète à exécuter (INSERT, DELETE, CREATE, UPDATE, SELECT ou SHOW ...)

 

Récupérer les résultats de vos requètes

Liste des enregistrements sélectionnés

Le résultat des requètes select ou show sera récupérable de la façon suivante:

  • MYSQL_RES *mysql_use_result(MYSQL *mysql)

Dans ce cas, MySQL pourra retourner un result set contenant les enregistrements sans que vous ayez besoin de réserver de la mémoire.

Vous devrez utiliser une autre commande pour lire séquentiellement les enregistrements et un par un. Inconvénient: pas de navigation libre comme retour en arrière, ...

Pour récupérer les enregistrements un à un de la liste des résultats, il faudra utiliser la commande MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

Cette commande retournera NULL lorsque vous aurez atteind la fin du result set ou si une erreur venait à se produire.

Cependant, il sera intéressant de connaître automatiquement le nombre de champs par enregistrement de la result set. D'où la commande suivante:

unsigned int mysql_num_fields(MYSQL_RES *result)

Et enfin, connaître la taille de la valeur stockée dans chacun des champs:

unsigned long *mysql_fetch_lengths(MYSQL_RES *result)

NoteLe principe de fonctionnement de cette fonction est similaire à MYSQL_ROW mysql_fetch_row(MYSQL_RES *result). L'information que vous allez récupérer ne se plus disponible ensuite, le prochain appel retournera la taillle de l'enregistrement suivant.

Voici un exemple de lecture de result set

  • MYSQL_RES *mysql_store_result(MYSQL *mysql) qui permet de stocker le result set dans une zone mémoire. A NULL s'il n'y a pas de result set.

La fonction peut retrouner des erreurs :

    • mysql_error() sous forme de texte (ou vide si pas d'erreur)
    • mysql_errno() pour un code erreur (ou 0 si pas d'erreur)
    • Notez que mysql_field_count() sera à 0 si erreur...

Le reste est identique à MYSQL_RES *mysql_use_result(MYSQL *mysql).

Le plus, c'est qu'il sera possible de naviguer dans cette zone mémoire:

void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset) avec offset, la position d'un enregistrement dans la resulset

ou MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset) qui utilise cette fois un n° interne d'enregistrement.

 

Nb. enregistrements sélectionnés, maj, créés ou supprimés

Après avoir récupéré, créé, supprimé, modifié votre result, vous pouvez vouloir récupérer d'autres informations: Le nombre de records maj ou lus.

NoteDe part le principe de fonctionne de la fonction MYSQL_RES *mysql_use_result(MYSQL *mysql) liée à sa lecture séquentielle sans retour possible, vous ne pouvez pas récupérer le nombre d'enregistrements tant que vous n'avez pas balayer tous les enregistrements de la result liste...

Préférez l'utilisation de MYSQL_RES *mysql_store_result(MYSQL *mysql) si vous avez besoin de connaître le nombre d'enregistrements avant le balayage des enregistrements !

my_ulonglong mysql_affected_rows(MYSQL *mysql) retourne le nombre d'enregistrements modifiés, supprimés ou créés depuis le dernier UPDATE, DELETE, or INSERT juste après un appel à mysql_query() ou mysql_real_query.

cf. http://dev.mysql.com/doc/refman/5.7/en/mysql-affected-rows.html pour plus de détails.

Avec une commande SELECT, il faut utiliser mysql_num_rows().

my_ulonglong mysql_num_rows(MYSQL_RES *result) retourne le nombre d'enregistrements trouvés lors d'un select.

Exemple:

my_ulonglong numRows=mysql_num_rows(result);
printf ("NB. records sélectionnés:%d", (unsigned long)numRows);

 

Libérer le result set

Que vous utilisiez MYSQL_RES *mysql_store_result(MYSQL *mysql) ou MYSQL_RES *mysql_use_result(MYSQL *mysql), il sera nécessaire de libérer les ressources:

void mysql_free_result(MYSQL_RES *result)

 

Afficher le dernier message d'erreur

const char *mysql_error(MYSQL *mysql) permet de récupérer le texte correspondant à la dernière erreur générée (ou une chaine vide si pas aucune erreur). Le texte sera terminé par un NULL.

if (mysql_query(&mysql, "select * from matable "))

mysql_error(mysql)

AttentionIl faut tester le retour des appels pour contrôler la présence d'une erreur. Alors dans ce cas, vous pourrez afficher le message avec cette fonction. En aucun cas se baser sur le résultat de cette fonction pour déterminer qu'une erreur a eu lieu lors d'un précédemment appel.

 

Compiler un programme Mysql

mysql_config est une commande qui va permettre de récupérer certains chemins comme celui des librairies. Il suffit de l'utiliser lors de la commande de compilation.

gcc main.c `mysql_config --cflags` `mysql_config --libs` -o testmysql

 

Annexes

MySQL et PHP

http://dev.mysql.com/doc/refman/5.7/en/c-api-functions.html pour avoir le détails des fonctions et des paramètres !