Cool C/C++

Programacion en C/C++

Home Tutoriales Programación C/C++ MySQL con Dev-C++
MySQL con Dev-C++ PDF Imprimir E-mail
Escrito por adrianvaca   
Domingo, 20 de Marzo de 2011 19:46
Indice del artículo
MySQL con Dev-C++
Instalación de MySQL
Instalación de MySQL-Front
Instalación de la librería para interacción con MySQL
Funciones básicas para interacción con MySQL
Proyecto de prueba en Dev-C++
Inserción, Actualización y eliminación de datos (Sistema de altas y bajas)
Todas las páginas

El presente tutorial tiene como objeto explicar en la forma más simple posible como acceder a una base de datos MySQL usando para ello el compilador Dev-C++, por lo que debes tenerlo instalado y configurado corréctamente, si no es así usas los siguiente links antes de continuar con este manual:

Descarga del Dev-C++
Instalación del Dev-C++


Bien, antes de ponernos a trabajar, primero deben saber que es necesario tener instalado y configurado el MySQL, luego hace falta instalar las librerías necesarias para poder acceder a la base de datos desde nuestros programas de C/C++ usando nuestro compilador.

Para una mayor comodidad he divido este tutorial en algunas secciones, que son las siguientes:

Instalación de MySQL
Instalación de MySQL-Front
Instalación de la librería para interacción con MySQL
Funciones básicas para interacción con MySQL
Proyecto de prueba en Dev-C++
Inserción, Actualización y eliminación de datos (Sistema de altas y bajas)




Esta sección supone que has descargado el siguiente archivo:

Instalador de MySQL (mysql-essential-win32.msi)


Instalación

  1. Damos doble click sobre el archivo y se nos presenta la pantalla de bienvenida:



    Le das click al botón Next para continuar


  2. Ahora se nos muestra el tipo de instalación que queremos seguir, escogemos Typical y damos click en Next:



  3. Aquí se nos presenta un resumen de las opciones de instalación escogidas, click en Install para iniciar el proceso de instalación:



  4. En esta parte se pide que nos suscribamos al sitio MySQL.com o que ingresemos los datos de nuestra cuenta, lo normal es seleccionar Skip Sign-Up y dar click en Next:



  5. Por último se muestra esta pantalla en la cual se indica que el proceso de instalación ha sido exitoso. Escogemos la opción Configure the MySQL Server now y click en Finish para terminar esta parte.





Configuración

  1. Una vez concluída la parte anterior, vamos a configurar nuestro servidor, aquí damos click en Next:



  2. Ahora seleccionamos la opción Standard Configuration, la cual es la opción más simple y asume que no tenemos instalado previamente MySQL, damos click en Next:



  3. En esta pantalla seleccionamos todas las opciones tal y como se muestra a continuación:



  4. Ahora seleccionamos la opción Modify Security Settings e ingresamos y confirmamos la clave del usuario root que es el administrador del servidor y damos click en Next:



  5. Aquí damos click en Execute para ejecutar las opciones de configuración seleccionadas:



  6. Una vez terminado el proceso click en Finish.






Al terminar hemos instalado y configurado de forma adecuada nuestro servidor MySQL




Esta sección supone que has descargado el siguiente archivo:

MySQL-Front (mysql-front.zip)


El MySQL-Front es un programa el cual permite administrar nuestro servidor MySQL de forma más fácil y gráfica, si no instalamos tendremos que administrar mediante consola, lo cual se vuelve tedioso.

Instalación

  1. Descomprimimos el archivo mysql-front.zip en cualquier directorio y veremos que aparecen algunos archivos, de ellos ejecutamos el MySQL-Front_Setup.exe y y se nos presenta la pantalla de bienvenida:



    Le das click al botón Siguiente para continuar


  2. Ahora se nos presenta el Acuerdo de Licencia, seleccionamos Acepto los términos del Acuerdo y click en Siguiente:



  3. Seleccionamos el directorio de instalación y proseguimos dando click en Siguiente:



  4. Aquí es nos muestra el nombre de la carpeta que tendrá los accesos directos en el Menú Inicio, lo normal es dejarlo como está y dar click en Siguiente:



  5. En esta pantalla dejamos las opciones por defecto y de nuevo click en Siguiente:



  6. Se nos presenta un resumen de las opciones de instalación y damos click en Instalar para iniciar el proceso:



  7. Una vez terminado se nos avisa que el proceso ha concluído de forma exitosa, seleccionamos la opción Launch MySQL-Front y damos click en Terminar





Configuración

  1. Una vez concluída la parte anterior, vamos a conifgurar el programa, se presenta entonces una pantalla en la cual debemos configurar los datos de acceso a nuestro servidor MySQL. En la pestaña Común, escribimos un nombre para nuestra sesión, en este caso en el cuadro Nombre escribimos local:



  2. En la pestaña Conexión, en el cuadro Servidor ingresamos el nombre o número ip de nuestro servidor MySQL, escribimos localhost para hacer referencia a nuestra máquina local:



  3. Ahora, en la pestaña Autetificación hay que ingresar los datos de un usuario válido para conectarnos, en este caso ingresamos el usuario root y la clave del mismo. (Esto fué especificado en el punto 4 sección Configuración del paso anterior de este manual)


    Damos click ahora en Aceptar.


  4. Podemos ver que se nos presenta una ventana con el listado de sesiones que hemos creado, en este caso seleccionamos local y damos click en Abrir:



  5. Ahora nos pide que ingresemos nuevamente nuestra clave de usuario, lo hacemos y de paso marcamos la opción Guardar contraseña para que no nos la vuelva a pedir y click en Aceptar:



  6. Por último podemos ver el entorno de nuestro programa, recomiendo familiarizarce con el mismo y revisar también la ayuda del programa para comprender mejor su manejo.






Al terminar hemos instalado y configurado de forma adecuada nuestro servidor MySQL-Front que como dije al inicio nos permitirá administrar nuestro servidor sin necesidad de acudir a la línea de comandos.

Mencionar también que con el archivo zip mencionado al inicio de esta sección, se incluye el archivo keygen.exe el cual nos sirve para generar un serial válido para que registrar nuestro programa (por medio del menú Ayuda) y que este no caduque.




Esta sección supone que has descargado el siguiente archivo:

Librería MySQL (libMySQL_DevCpp.zip)


Instalación

  1. Descomprime el archivo MySQL_DevCpp.zip y verás que aparece el archivo libmysql-5.0.5-1sid.DevPak le das doble click y se muestra la siguiente pantalla:



    Le das click al botón Next para continuar


  2. Ahora se nos muestra el acuerdo de licencia, dando click en Install se iniciará la instalación:



  3. Por último se muestra esta pantalla en la cual se indica que el proceso de instalación ha sido exitoso. Escogemos la opción Finish para terminar esta parte.





Consideraciones finales

  • Para poder usar la librería en nuestros programas debemos incluírlas con #include, mediante las líneas siguiente:

    #include <mysql/mysql.h>
    #include <mysql/mysqld_error.h> 



  • Además para poder compilar el proyecto debemos ir a Proyecto -> Opciones del Proyecto -> Parámetros y en el cuadro Linker escribir:

    -lmysql 


    Con esto no tendremos problemas y todo irá bien.





Al terminar hemos instalado la librería de forma adecuada y estamos listos para el siguiente paso.




Hay al menos 4 pasos que siempre haremos cuando trabajemos con MySQL, estos son:


  1. Inicializar un objeto de tipo MYSQL usando mysql_init

  2. Conectarnos a MySQL usando mysql_real_connect

  3. Realizar operaciones con la base de datos

  4. Cerrar la conexión usando mysql_close



Para una referencia completa de todas las funciones para acceso a una base de MySQL se encuentra en este archivo (manual_mysql.zip)

A continuación vamos a detallara las funciones más importantes, las cuales está disponibles con la instalación de la librería anterior:



Función

MYSQL *mysql_init(MYSQL *objDatos


Descripción

Inicializa un objeto de tipo MYSQL y lo deja listo para ser usado con mysql_real_connect y establecer una conexión. Si mysql es un puntero NULL la función asigna la memoria, iniciliza y retorna un nuevo objeto. En caso contrario el objeto es inicilizado y se retorna la dirección del mismo. Si mysql_init asigna memoria a un nuevo objeto, esta será liberada cuando se llame a mysql_close para cerra la conexión.

Valor de retorno

Un puntero a un objeto de tipo MYSQL, si no hay memoria retorna NULL.

Ejemplo

MYSQL *objDatos;
 
// Intentar iniciar MySQL:
if(!(objDatos = mysql_init(0))) {
   // Imposible crear el objeto objMySQL
   return 1;
}



Función

MYSQL *mysql_real_connect (MYSQL *objDatos, const char *host,
 const 
char *user, const char *passwd,
 const 
char *dbunsigned int port, const char *unix_socketunsigned long client_flag


Descripción

Intenta establecer una conexión con el servidor MySQL, los parámetros son:


  1. Puntero a objeto de tipo MYSQL, iniciado antes con mysql_init

  2. El nombre de la máquina o número ip del servidor de MySQL. Podemos ingresar localhost para hacer referencia a la máquina local.

  3. El nombre de usuario. Bajo Unix es el usuario logeado actualmente, esto se indica con NULL. Bajo Windows ODBC debe ser ingresado.

  4. La contraseña del usuario.

  5. Base de datos por defecto, para no especificar base ingresamos NULL

  6. El número de puerto usado para la conexión TCP/IP, es mejor ingresar MYSQL_PORT para usar el valor por defecto.

  7. Socket Unix, para conexiones locales colocar NULL.

  8. Usualmente es 0.


Valor de retorno

Si retorna NULL indica que no se pudo establecer la conexión.

Ejemplo

if(!mysql_real_connect(objDatos, NULL, "usuario", "clave", "base_ejemplo", MYSQL_PORT, NULL, 0)) {
      // No se puede conectar con el servidor en el puerto especificado.
      cout << "Imposible conectar con servidor mysql en el puerto "
           << MYSQL_PORT << endl;
      mysql_close(objDatos);
      return 1;
}



Función

void mysql_close(MYSQL *objDatos


Descripción

Cierra una conexión previamente abierta. Libera la memoria asignada para la conexión

Valor de retorno

Ninguno

Ejemplo

mysql_close(objDatos);



Función

int mysql_ping(MYSQL *objDatos


Descripción

Chequea si la conexión del servidor está activa. Si la conexión no está activa automáticamente intenta reconectarse. Esto puede ser usado si no interactuamos con el servidor por un largo período de tiempo
Con esto no tendremos problemas y todo irá bien.

Valor de retorno

0 si el servidor está arriba. Distinto de 0 sdi ocurrió algún error.

Ejemplo

if(mysql_ping(objDatos)) {
      cout << "Error: conexión imposible" << endl;
      mysql_close(objDatos);
}



Función

const char *mysql_error(MYSQL *objDatos


Descripción

Retorna un string que contiene el mensaje de error para la función más recientemente invocada. Si la función falla el valor de retorno debería ser el error previo. Si no hay error retorna un string vacío. Un regla a tomar en cuenta es que después de llamara auna función que interactúa con MySQL se llame a mysql_error para saber si ocurió o no algún error.

Valor de retorno

Un string con la descripción del error.

Ejemplo

if(mysql_error(objDatos)[0] != '\0')
{
    // Ocurrio un error
}



Función

int mysql_select_db(MYSQL *objDatos, const char *db


Descripción

Hace que la base de datos especificada por db sea la base actual de la conexión. En consultas subsecuentes, será utilizada dicha base. mysql_select_db falla si el usuario especificado no tiene permisos para usar la base.

Valor de retorno

0 si hay éxito. Distinto de 0 en caso de error.

Ejemplo

if(mysql_select_db(objDatos, "base_ejemplo")) {
      // Error al seleccionar base de datos.
      cout << "ERROR: " <<  mysql_error(objDatos) << endl;
      mysql_close(objDatos);
      rewind(stdin);
      getchar();
      return 2;
}



Función

int mysql_query(MYSQL *objDatos, const char *query


Descripción

Ejecuta una consulta SQL. Debe ser sólo una instrucción. No se puede usar para consultas que tienen datos binarios. Se puede usar para ejecutar instrucciones SELECT, INSERT o UPDATE

Valor de retorno

0 si hay éxito. Distinto de 0 en caso de error.

Ejemplo

// Hacer una consulta con el comando "SELECT * FROM personas":
if(mysql_query(objDatos, "SELECT * FROM personas")) {
      // Error al realizar la consulta:
      cout << "ERROR: " <<  mysql_error(objDatos) << endl;
      mysql_close(objDatos);
      rewind(stdin);
      getchar();
      return 2;
}



Función

MYSQL_RES *mysql_store_result(MYSQL *objDatos


Descripción

Se debe llamar a mysql_store_result o mysql_use_result para cada consulta que exitósamente obtuvo datos. No se debe llamar a mysql_store_result o mysql_use_result para otras consultas. mysql_store_result lee el conjunto completo de resultados y lo coloca en una estructura. Retorna NULL si la cinsulta no devuelve resultados, por ejemplo una instrucción INSERT. Después de usarla se debe llamar a mysql_free_result para liebrar recursos.

Valor de retorno

Una estructura MYSQL_RES con los resultados o NULL si hay algune error.

Ejemplo

// Almacenar el resultado de la consulta, lo necesitaremos después:
if((res = mysql_store_result(objDatos))) {
   // Procesar resultados
   ...
   // Liberar el resultado de la consulta:
   mysql_free_result(res);
}



Función

unsigned long mysql_num_rows(MYSQL_RES *res


Descripción

Retorna el número de filas en el conjunto de resultados

Valor de retorno

El número de filas

Ejemplo

if((res = mysql_store_result(objDatos))) {
   // Numero de filas
   int i = (int) mysql_num_rows(res);
   // Liberar el resultado de la consulta:
   mysql_free_result(res);
}



Función

unsigned long mysql_num_fields(MYSQL_RES *result


Descripción

Retorna el número de columnas en el conjunto de resultados.

Valor de retorno

El número de columnas

Ejemplo

if((res = mysql_store_result(objDatos))) {
   // Numero de columnas
   int j = (int) mysql_num_fields(res);
   // Liberar el resultado de la consulta:
   mysql_free_result(res);
}


Ejemplo

Obtener el número de filas y columas

   i = (int) mysql_num_rows(res);
   j = (int) mysql_num_fields(res);
   // Mostrar el número de registros seleccionados:
   cout << "Consulta:  SELECT * FROM personas" << endl;
   cout << "Numero de filas encontradas:  " << i << endl;
   cout << "Numero de columnas por fila:  " << j << endl;



Función

MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *res


Descripción

Retorna la definición de una de las columnas como una estructura de tipo MYSQL_FIELD Se puede llamar sucesivamente para obtener información de todas las columnas.

Valor de retorno

Una estructura de tipo MYSQL_FIELD para la columna actual o NULL si no faltan columnas.

Ejemplo

for(int l = 0; l < j; l++) {
      columna = mysql_fetch_field(res);
      cout << "Nombre: " << columna->name << endl;
      cout << "Longitud: " << columna->length << endl;
      cout << "Valor por defecto: " << (columna->def ? columna->def : "NULL") << endl;
}



Función

MYSQL_ROW mysql_fetch_row(MYSQL_RES *res


Descripción

Obtiene la siguiente fila de un conjunto de resultados. Retorna nulo si no hay más filas.

Valor de retorno

Una estructura de tipo MYSQL_ROW o NULL si no hay filas o si ocurrió algún error.

Ejemplo

for(l = 0; l < i; l++) {
      row = mysql_fetch_row(res);
      cout << "Registro no. " << l+1 << endl;
      // Mostrar cada campo:
      for(k = 0 ; k < j ; k++)
         cout << ((row[k]==NULL) ? "NULL" : row[k]) << endl;
}



Función

unsigned long *mysql_fetch_lengths(MYSQL_RES *res


Descripción

Retorna la longitud de las columnas para la fila actual. Para columnas que contienen NULL retorna 0

Valor de retorno

Un arreglo de tipo unsigned long que representa el tamaño de cada columna o NULL si hay error.

Ejemplo

// Leer registro a registro y mostrar:
   l=1;
   for(l = 0; l < i; l++) {
      row = mysql_fetch_row(res);
      lon = mysql_fetch_lengths(res);
      cout << "Registro no. " << l+1 << endl;
      // Mostrar cada campo y su longitud:
      for(k = 0 ; k < j ; k++) {
         cout << ((row[k]==NULL) ? "NULL" : row[k]);
         cout << " longitud: " << lon[k] << endl;
      }
   }



Función

void mysql_data_seek(MYSQL_RES *resunsigned long offset


Descripción

mysql_fetch_row permite acceder a filas en forma secuencial, pero mysql_data_seek busca una fila determinada en un conjunto de resultados. El valor de offset debe estar entre 0 y mysql_num_rows(res)-1. Esta función precisa el conjunto completo de resultados, es decir debe usarse en conjunto con mysql_store_result y NO debe usarse con mysql_use_result.

Valor de retorno

Ninguno.

Ejemplo

// 3ª fila:
   mysql_data_seek(res, 2);
   row = mysql_fetch_row(res);
   cout << "Tercera fila" << endl;
   for(k = 0 ; k < j ; k++) {
      cout << ((row[k]==NULL) ? "NULL" : row[k]) << endl;
   }



Función

MYSQL_RES *mysql_use_result(MYSQL *objDatos


Descripción

Para conjuntos muy grandes de rsultados no es conveniente almacenar todo el conjunto de datos ya que esto consume memoria extra, es mejor acceder a los registros uno por uno. Se debe llamar a mysql_store_result o mysql_use_result para cada consulta que exitósamente obtuvo datos. Se debe llamar a esta función para liberra recursos luego de ejecutar una sentencia o consulta. No se debe llamar a mysql_store_result o mysql_use_result para otras consultas.

Valor de retorno

Una estructura de tipo MYSQL_RES o NULL si hay error.

Ejemplo

// El mismo proceso usando mysql_use_result:
   // Hacer una consulta con el comando "SELECT * FROM personas":
   if(mysql_query(objDatos, "SELECT * FROM personas")) {
      // Error al realizar la consulta:
      cout << "ERROR: " <<  mysql_error(objDatos) << endl;
      mysql_close(objDatos);
      return 2;
   }
   if((res = mysql_use_result(objDatos))) {
      j = (int) mysql_num_fields(res);
      while(row = mysql_fetch_row(res)) {
         for(k = 0 ; k < j ; k++)
            cout << ((row[k]==NULL) ? "NULL" : row[k]) << endl;
      }

      // Liberar el resultado de la consulta:
      mysql_free_result(res);
   }




Bien, ahora que sabemos las funciones básicas que nos permiten acceder a MySQL, podemos crear nuestro proyecto en Dev-C++, pero primero vamos a crear una base de datos para pruebas, la cual tendrá una tabla y 3 registros para poder jugar con ellos.

Creación de la base de prueba


  1. Abrimos el MySQL-Front y se nos presenta la ventana:



    Damos click en abrir para poder ingresar, si nos pide la clave la ingresamos.


  2. Una vez que ingresemos damos click sobre el botón Editor SQL para que se despliegue una ventana de comandos en la cual podamos ejecutar instrucciones SQL.

    En dicha ventana pegamos el siguiente código:

    CREATE DATABASE base_ejemplo;

    USE base_ejemplo;

    CREATE TABLE personas (
      id int(3) NOT NULL auto_increment,
      nombre varchar(20) default NULL,
      apellido varchar(20) default NULL,
      edad int(3) NOT NULL default '0',
      direccion varchar(40) default NULL,
      PRIMARY KEY  (id)
    ) AUTO_INCREMENT=1 ;

    INSERT INTO personas(nombre, apellido, edad, direccion) VALUES('adrian', 'vaca', 25, 'Santiago 222');
    INSERT INTO personas(nombre, apellido, edad, direccion) VALUES('karla', 'aguirre', 26, 'Ventimilla y 6 de diciembre');
    INSERT INTO personas(nombre, apellido, edad, direccion) VALUES('pedro', 'vela', 48, '10 de Agosto y Guevara');

    SELECT * FROM personas;


    Y se nos presenta la siguiente ventana:



Bien lo que hemos hecho aquí es lo siguiente:


  • Creamos una base de nombre base_ejemplo con la sentencia CREATE DATABASE

  • Con USE base_ejemplo establecemos la base base_ejemplo como la base actual ya que en esta vamos a ejecutar los comandos a continuación.

  • Con CREATE TABLE personas creamos una tabla cuyo nombre es personas que tienen las columnas especificadas.

  • Luego insertamos 3 registros en dicha tabla. Fíjense que no mencionamos a la columna id debido a que cuando definimos dicha columna al crear la tabla le pusimos el atributo auto_increment con lo cual el valor de la columna será incrementada en forma automática en 1.

  • Con SELECT * FROM personas
  • seleccionamos todos los registros de la tabla personas y los resultados se muestran en la parte inferior de la pantalla.


Bien hemos terminado esta parte.



Creación del proyecto con Dev-C++

Los pasos como siempre son los siguientes:


  1. Abrimos el Dev-C++, vamos a Archivo -> Nuevo -> Proyecto, en la pestaña Basic seleccionamos Console Application y el nombre del proyecto será PruebaMySQL



    Guardamos el archivo del proyecto.


  2. Vamos a Proyecto -> Opciones del proyecto -> Parámetros y en el cuadro Linker, escribimos -lmysql tal como se muestra a continuación:



  3. Ahora reemplazamos el código de la ventana por el siguiente:

    /*
      Name: main.cpp
      Author: Salvador Pozo Coronado, Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla
      Date: 07/05/2005
      Description: Ejemplo para mostrar contenidos de bases de datos
      usando MySQL.
    */

    // Includes...
    #include <iostream>
    #include <windows.h>
    #include <mysql/mysql.h>
    #include <mysql/mysqld_error.h>
    #include <cstring>
    #include <cstdio>

    using namespace std;

    // Programa principal
    int main()
    {
       // Variables
       MYSQL           *objDatos;
       MYSQL_RES       *res;
       MYSQL_ROW        row;
       MYSQL_FIELD     *columna;
       int              i, j, k, l;
       unsigned long   *lon;
       MYSQL_ROW_OFFSET pos;

       // Intentar iniciar MySQL:
       if(!(objDatos = mysql_init(0))) {
          // Imposible crear el objeto objDatos
          cout << "ERROR: imposible crear el objeto objDatos." << endl;
          rewind(stdin);
          getchar();
          return 1;
       }

       // Debe existir un usuario "root" con clave de acceso "clave"
       if(!mysql_real_connect(objDatos, NULL, "root", "clave", "base_ejemplo", MYSQL_PORT, NULL, 0)) {
          // No se puede conectar con el servidor en el puerto especificado.
          cout << "Imposible conectar con servidor mysql en el puerto "
               << MYSQL_PORT << " Error: " << mysql_error(objDatos) << endl;
          mysql_close(objDatos);
          rewind(stdin);
          getchar();
          return 1;
       }

       // Conectar a base de datos.
       if(mysql_select_db(objDatos, "base_ejemplo")) {
          // Imposible seleccionar la base de datos, posiblemente no existe.
          cout << "ERROR: " << mysql_error(objDatos) << endl;
          mysql_close(objDatos);
          rewind(stdin);
          getchar();
          return 2;
       }
     
       // Hacer una consulta con el comando "SELECT * FROM personas":
       if(mysql_query(objDatos, "SELECT * FROM personas")) {
          // Error al realizar la consulta:
          cout << "ERROR: " <<  mysql_error(objDatos) << endl;
          mysql_close(objDatos);
          rewind(stdin);
          getchar();
          return 2;
       }

       // Almacenar el resultado de la consulta:
       if((res = mysql_store_result(objDatos))) {
          // Obtener el número de registros seleccionados:
          i = (int) mysql_num_rows(res);
          // Obtener el número de columnsa por fila:
          j = (int) mysql_num_fields(res);

          // Mostrar el número de registros seleccionados:
          cout << "Consulta:  SELECT * FROM personas" << endl;
          cout << "Numero de filas encontradas:  " << i << endl;
          cout << "Numero de columnas por fila:  " << j << endl;
     
          // Información sobre columnas usando mysql_fetch_field:
          cout << endl << "Informacion sobre columnas:" << endl;
          for(l = 0; l < j; l++) {
             columna = mysql_fetch_field(res);
             cout << "Nombre: " << columna->name << endl;
             cout << "Longitud: " << columna->length << endl;
             cout << "Valor por defecto: " << (columna->def ? columna->def : "NULL") << endl;
          }
          cout << endl;

          // Información sobre columnas usando mysql_fetch_fields:
          cout << endl << "Informacion sobre columnas:" << endl;
          columna = mysql_fetch_fields(res);
          for(l = 0; l < j; l++) {
             cout << "Nombre: " << columna[l].name << endl;
             cout << "Longitud: " << columna[l].length << endl;
             cout << "Valor por defecto: " << (columna[l].def ? columna[l].def : "NULL") << endl;
          }
          cout << endl;

          // Información sobre columnas n, usando mysql_fetch_field_direct:
          cout << endl << "Informacion sobre columna 1:" << endl;
          columna = mysql_fetch_field_direct(res, 1);
          cout << "Nombre: " << columna->name << endl;
          cout << "Longitud: " << columna->length << endl;
          cout << "Valor por defecto: " << (columna->def ? columna->def : "NULL") << endl;
          cout << endl;

          // Leer registro a registro y mostrar:
          l=1;
          for(l = 0; l < i; l++) {
             row = mysql_fetch_row(res);
             lon = mysql_fetch_lengths(res);
             cout << endl << "Registro no. " << l+1 << endl;
             // Mostrar cada campo y su longitud:
             for(k = 0 ; k < j ; k++) {
                cout << ((row[k]==NULL) ? "NULL" : row[k]);
                cout << " longitud: " << lon[k] << endl;
             }
          }
         
          cout << endl;
         
          // Mostrar sólo 3ª fila:
          mysql_data_seek(res, 2);
          row = mysql_fetch_row(res);
          cout << "Tercera fila" << endl;
          for(k = 0 ; k < j ; k++) {
             cout << ((row[k]==NULL) ? "NULL" : row[k]) << endl;
          }

          // Liberar el resultado de la consulta:
          mysql_free_result(res);
       }
       
       // El mismo proceso usando mysql_use_result:
       // Hacer una consulta con el comando "SELECT * FROM personas":
       if(mysql_query(objDatos, "SELECT * FROM personas")) {
          // Error al realizar la consulta:
          cout << "ERROR: " <<  mysql_error(objDatos) << endl;
          mysql_close(objDatos);
          rewind(stdin);
          getchar();
          return 2;
       }
       
       // Mostrar todas las filas:
       if((res = mysql_use_result(objDatos))) {     
          j = (int) mysql_num_fields(res);
          cout << endl << endl << "Mostrando filas usando: mysql_use_result";
          while(row = mysql_fetch_row(res)) {
             for(k = 0 ; k < j ; k++)
                cout << ((row[k]==NULL) ? "NULL" : row[k]) << endl;
          }

          // Liberar el resultado de la consulta:
          mysql_free_result(res);
       }
       
       // Cerrar la conexión
       mysql_close(objDatos);
       
       // Esperar a que se pulse una tecla y salir.
       rewind(stdin);
       getchar();
       return 0;
    }


    Tomar en cuenta que se debe reeplazar la palabra clave por la contraseña real del usuario root.

    Presionamos CTRL+S para guardar el archivo mostrado (main.cpp)


  4. Presionamos CTRL+F9 para compilar el programa y CTRL+F10 para ejecutarlo. El resultado será entonces mostrado en pantalla:









Deben revisar bien el código fuente y comprenderlo, aquí se trata lo escencial de operaciones con MySQL desde C++




Bien, ahora que ya hemos hecho un proyecto de prueba y sabemos las funciones básicas para interactuar con MySQL desde nuestros programas, vamos a ir creando paso a paso un simple pero funcional sistema de altas y bajas, en el cual estén incluídas todas las operaciones que normalmente realizamos, tales como: búsqueda, inserción, modificación, eliminación.

El código fuente completo del proyecto descárguenlo aquí

Primero vamos a crear una clase que nos permita acceder a una base de datos de MySQL de forma simple, la idea es poder reutilizar esta clase en nuestros proyectos que necesiten acceder a una base de este tipo.

Bien la definición de nuestra clase que permite efectuar operaciones con una base MySQL es:

#include <windows.h>
#include <mysql/mysql.h>
#include <mysql/mysqld_error.h>

class sql_db 
{
   private:
     
char *servidor, *usuario, *password, *database;            
     
MYSQL *objDatos;
                  
   public:
     
sql_db(char *servidorchar *usuariochar *passwordchar *database);
     ~
sql_db();
     
void sql_close();        
     
MYSQL_RES ejecutar_sql(char *sql);
     
int numero_filas(MYSQL_RES *res);
     
int filas_afectadas();
     
int numero_columnas(MYSQL_RES *res);
     const 
char *nombre_columna(MYSQL_RES *resint indice);
     
int longitud_columna(MYSQL_RES *resint indice);
     const 
char *valor_defecto_columna(MYSQL_RES *resint indice);
     
MYSQL_ROW obtener_fila(MYSQL_RES *res);
     
void fijar_fila(MYSQL_RES *resint indice);
     
unsigned long ultimo_id();
}; 


Y la implementación de los métodos es:

sql_db :: sql_db (char *servidor, char *usuario, char *password, char *database)
{
    this->servidor = servidor;
    this->usuario = usuario;
    this->password = password;
    this->database = database;
   
   // Intentar iniciar MySQL:
   if(!(objDatos = mysql_init(0))) {
      // Imposible crear el objeto objDatos
      cout << "ERROR: imposible crear el objeto objDatos." << endl;
      getchar();
      exit(1);
   }

   // Debe existir un usuario "root" con clave de acceso "clave"
   if(!mysql_real_connect(objDatos, this->servidor, this->usuario, this->password, this->database, MYSQL_PORT, NULL, 0)) {
      // No se puede conectar con el servidor en el puerto especificado.
      cout << "Imposible conectar con servidor mysql en el puerto "
           << MYSQL_PORT << " Error: " << mysql_error(objDatos) << endl;
      mysql_close(objDatos);
      rewind(stdin);
      getchar();
      exit(2);
   }
}

sql_db :: ~sql_db()
{
   this->sql_close();
}

void sql_db :: sql_close()
{   
   mysql_close(this->objDatos);
}

MYSQL_RES * sql_db :: ejecutar_sql(char *sql)
{
   if(mysql_ping(objDatos)) {
      cout << "Error: conexión imposible" << endl;
      this->sql_close();
   }
             
   if(mysql_query(objDatos, sql)) {
      // Error al realizar la consulta:
      cout << "ERROR: " <<  mysql_error(objDatos) << endl;
      this->sql_close();
      rewind(stdin);
      getchar();
      exit(2);
   }

   return mysql_store_result(objDatos);
}

int sql_db :: numero_filas(MYSQL_RES *res)
{
    return mysql_num_rows(res);
}

int sql_db :: filas_afectadas()
{
    return mysql_affected_rows(this->objDatos);
}

int sql_db :: numero_columnas(MYSQL_RES *res)
{
    return mysql_num_fields(res);
}

const char * sql_db :: nombre_columna(MYSQL_RES *res, int indice)
{
    return mysql_fetch_field_direct(res, indice)->name;
}

int sql_db :: longitud_columna(MYSQL_RES *res, int indice)
{
    return mysql_fetch_field_direct(res, indice)->length;
}

const char * sql_db :: valor_defecto_columna(MYSQL_RES *res, int indice)
{
    MYSQL_FIELD *col = mysql_fetch_field_direct(res, indice);
    return col->def ? col->def : "NULL";
}

MYSQL_ROW  sql_db :: obtener_fila(MYSQL_RES *res)
{
    return mysql_fetch_row(res);
}

void sql_db :: fijar_fila(MYSQL_RES *res, int indice)
{
     mysql_data_seek(res, indice);
}

unsigned long sql_db :: ultimo_id()
{
    return (unsigned long )mysql_insert_id(this->objDatos);
}


Bien, ahora para continuar diseñemos el program principal.

La definición de la tabla que ya creamos en la parte anterior de este tutorial es:

CREATE TABLE personas (
  
id int(3NOT NULL auto_increment,
  
nombre varchar(20) default NULL,
  
apellido varchar(20) default NULL,
  
edad int(3NOT NULL default '0',
  
direccion varchar(40) default NULL,
  
PRIMARY KEY  (id)
AUTO_INCREMENT=



Esta tabla ha sido creada en nuestra base llamada base_ejemplo.

Ahora vamos a crear una estructura de datos para poder representar esta misma tabla, pero en nuestro programa de C/C++, la definición de la estructura es la siguiente:

struct persona
   
int id
   
char nombre[20]; 
   
char apellido[20]; 
   
int edad
   
char direccion[40]; 
}; 



Fíjense que hemos definidos los mismos nombres tanto para los campos en la tabla como para los elementos de la estructura, aunque esto no es necesario.
Lo importante aquí es que los campos de la estructura sean lo más parecidos posible a los campos de la tabla en cuanto a tipos de dato y longitud, es decir si el campo en la tabla es int(3) en nuestra estructura el elemento será int, si en la tabla es varchar(20), en la estructura será char [20] y así sucesivamente.

Para poder trabajar en mejor forma vamos a definir un tipo de dato para nuestra estructura con la línea siguiente:

typedef struct persona Persona


Luego vamos a definir un objeto de tipo sql_db en el cual especificamos los parametros de conexion a la base, estos son: servidor, usuario, clave y base inicial:

sql_db obj_mysql("localhost""root""clave""base_ejemplo"); 


Ahora veamos los prototipos de las funciones en nuestro programa:

void ingresar(), insertar(Persona info); 
void buscar(), modificar(), actualizar(Persona info), eliminar();
void ordenar(), mostrar(); 
char menu(void); void pausa(); 


Y su implementación es:

void ingresar()
{
   Persona info;

   cout << "Ingrese nombre: ";
   cin >> info.nombre;
   cout << "Ingrese apellido: ";
   cin >> info.apellido;
   cout << "Ingrese edad: ";
   cin >> info.edad;
   cout << "Ingrese direccion: ";
   cin >> info.direccion;   
   insertar(info);
   cout << "Persona ingresada exitosamente" << endl;
}

void insertar(Persona info)

   char *consulta;
   char sentencia[] = "INSERT INTO personas(nombre, apellido, edad, direccion) VALUES('%s', '%s', %d, '%s')";
   
   consulta = new char[strlen(sentencia)+sizeof(Persona)-sizeof(int)];   
   sprintf(consulta, sentencia, info.nombre, info.apellido, info.edad, info.direccion);
   
   obj_mysql.ejecutar_sql(consulta);
}

void buscar()
{
   char nombre[20];
   char *consulta;
   char sentencia[] =  "SELECT * FROM personas WHERE nombre='%s'";
   MYSQL_RES *res;
   MYSQL_ROW  row;   
   
   cout << "Ingrese nombre a buscar: ";
   cin >> nombre;
   
   consulta = new char[strlen(sentencia)+strlen(nombre)];   
   sprintf(consulta, sentencia, nombre);
   res = obj_mysql.ejecutar_sql(consulta);
   
   if(obj_mysql.filas_afectadas()>0)
   {
       row = obj_mysql.obtener_fila(res);
      cout << "Id: " << row[0] << endl;
      cout << "Nombre: " << row[1] << endl;      
      cout << "Apellido: " << row[2] << endl;      
      cout << "Edad: " << row[3] << endl;
      cout << "Direccion: " << row[4] << endl;             
   }
   else
      cout << "Persona no encontrada" << endl;
}

void modificar()
{
   char nombre[20];
   char *consulta;
   char *temp;
   char sentencia[] = "SELECT * FROM personas WHERE nombre='%s'";
   MYSQL_RES *res;
   MYSQL_ROW  row;   
   Persona info;
   
   cout << "Ingrese nombre a modificar: ";
   cin >> nombre;

   consulta = new char[strlen(sentencia)+strlen(nombre)];   
   sprintf(consulta, sentencia, nombre);
   res = obj_mysql.ejecutar_sql(consulta);

   if(obj_mysql.filas_afectadas()>0)
   {
       row = obj_mysql.obtener_fila(res);
       sprintf(temp, "%s", row[0]);
       info.id = atoi(temp);
       cout << "Ingrese nombre: ";
       cin >> info.nombre;
       cout << "Ingrese apellido: ";
       cin >> info.apellido;
       cout << "Ingrese edad: ";
       cin >> info.edad;
       cout << "Ingrese direccion: ";
       cin >> info.direccion;         
       actualizar(info);
       cout << "Datos actualizados exitosamente" << endl;       
   }
   else
      cout << "Persona no encontrada" << endl;
}

void actualizar(Persona info)
{
   char nombre[20];
   char *consulta;
   char sentencia[] = "UPDATE personas SET nombre='%s', apellido='%s', edad=%d, direccion='%s' WHERE id=%d";
   
   consulta = new char[strlen(sentencia)+strlen(nombre)];   
   sprintf(consulta, sentencia, info.nombre, info.apellido, info.edad, info.direccion, info.id);
   obj_mysql.ejecutar_sql(consulta);
}

void eliminar()
{
   char nombre[20];
   char *consulta;
   char *temp;
   char sentencia_buscar[] = "SELECT * FROM personas WHERE nombre='%s'";
   char sentencia_eliminar[] = "DELETE FROM personas WHERE id=%d";
   MYSQL_RES *res;
   MYSQL_ROW  row;   
   Persona info;
   
   cout << "Ingrese nombre a eliminar: ";
   cin >> nombre;

   consulta = new char[strlen(sentencia_buscar)+strlen(nombre)];   
   sprintf(consulta, sentencia_buscar, nombre);
   res = obj_mysql.ejecutar_sql(consulta);

   if(obj_mysql.filas_afectadas()>0)
   {
       row = obj_mysql.obtener_fila(res);
       sprintf(temp, "%s", row[0]);
       int id = atoi(temp);
       consulta = new char[strlen(sentencia_eliminar)+sizeof(int)];   
       sprintf(consulta, sentencia_eliminar, id);
       obj_mysql.ejecutar_sql(consulta);
       cout << "Datos eliminados exitosamente" << endl;       
   }
   else
      cout << "Persona no encontrada" << endl;
}

void ordenar()
{   
   MYSQL_RES *res;
   MYSQL_ROW row;
   int filas, columnas;
   
   res = obj_mysql.ejecutar_sql("SELECT * FROM personas ORDER BY nombre");
   filas = obj_mysql.numero_filas(res);
   columnas = obj_mysql.numero_columnas(res);
   
   cout << "--- Listado de personas ("  << filas << ") ---" << endl;
   
   for(int j=0; j < columnas; j++)
       cout << obj_mysql.nombre_columna(res, j) <<  " - ";
   cout << endl;

   while(row = obj_mysql.obtener_fila(res))
   {
       for(int j=0; j < columnas; j++)
       {
           cout << row[j] << ", ";
       }
       cout << endl;
   }   
   cout << "Se han ordenado los registros por: nombre" << endl;
}

void mostrar()
{
   MYSQL_RES *res;
   MYSQL_ROW row;
   int filas, columnas;
   
   res = obj_mysql.ejecutar_sql("SELECT * FROM personas");
   filas = obj_mysql.numero_filas(res);
   columnas = obj_mysql.numero_columnas(res);
   
   cout << "--- Listado de personas ("  << filas << ") ---" << endl;
   
   for(int j=0; j < columnas; j++)
       cout << obj_mysql.nombre_columna(res, j) <<  " - ";
   cout << endl;

   while(row = obj_mysql.obtener_fila(res))
   {
       for(int j=0; j < columnas; j++)
       {
           cout << row[j] << ", ";
       }
       cout << endl;
   }   
}


char menu(void)
{
   char c;
   cout << "(1)Ingresar, (2)Buscar, (3)Modificar, (4)Eliminar, (5)Ordenar, (6)Mostrar lista, (7)Salir" << endl;

   printf("Seleccion: ");
   c=getchar();
   cout << endl;
   return(c);
}

void pausa()
{
   cout << endl;
   system("PAUSE");
   cout << endl;
}



Por fin la función main, quedará así:

int main(int argcchar *argv[])
{
   
system("CLS"); 
   
char op

   for( ; ; ) 
   { 
     
fflush(stdin);
     switch(
op=menu()) 
     { 
        case 
'1'
           
ingresar(); 
           
pausa(); 
           break; 
        case 
'2'
           
buscar(); 
           
pausa();
           break; 
        case 
'3'
           
modificar(); 
           
pausa(); 
           break; 
        case 
'4'
           
eliminar(); 
           
pausa(); 
           break; 
        case 
'5'
           
ordenar(); 
           
pausa();
           break; 
        case 
'6'
           
mostrar(); 
           
pausa(); 
           break; 
        case 
'7'
           break; 
        default : 
           
cout << "Opcion no valida"
           
pausa();
           break; 
     } 

     if(
op=='7') break; 
     
system("CLS"); 
   } 

   return 
0;


El código fuente completo del proyecto descárguenlo aquí

Y eso es todo, no damos más explicación para que revisen el código y traten de entenderlo por ustedes mismo, en realidad no es complicado.


 
Otros artículos

Comentarios  

 
0 #3 Roberto Carlos Silva Orozco 29-02-2020 19:44
Cito a may:
Hola, Buenas tardes.
Tengo problemas con el #include de mysql, me dice que no encuentra el archivo ni el directorio y ya hice todo lo que se tenia que hacer.
Espero y puedan ayudarme, gracias.

Justo tuve ese problema, debes de incluir en tu proyecto en la parte de directorios include el include de DEVCPP.
Citar
 
 
0 #2 Luis 28-10-2019 17:12
Cito a may:
Hola, Buenas tardes.
Tengo problemas con el #include de mysql, me dice que no encuentra el archivo ni el directorio y ya hice todo lo que se tenia que hacer.
Espero y puedan ayudarme, gracias.

Prueba instalar DEV c++ 4.9. Eso me funcionó
Citar
 
 
0 #1 may 22-10-2018 15:56
Hola, Buenas tardes.
Tengo problemas con el #include de mysql, me dice que no encuentra el archivo ni el directorio y ya hice todo lo que se tenia que hacer.
Espero y puedan ayudarme, gracias.
Citar
 

Escribir un comentario


Código de seguridad
Refescar