programacion aplicaciones mysql con c

34

Upload: maurino-luis-condor-zanabria

Post on 02-Jan-2016

37 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Programacion Aplicaciones MySQL Con C
Page 2: Programacion Aplicaciones MySQL Con C

Programación de aplicaciones MySQL con C

En este documento se da una introducción al uso del API C que proporciona MySQL para el desarrollo de aplicaciones.

Autor: Jorge Jesús Churruca

Fecha publicación: 22 Junio del 2004

Acerca de esta guía

Este documento pretende ser no sólo una traducción del original (el cual viene junto al manual de MySQL), sino también, un agregado con mejoras, resúmenes, más ejemplos de códigos, explicaciones más detalladas, y las páginas "man" de las funciones más importantes (que no vienen con el original), etc., para hackers de MySQL. Actualmente se han omitido algunas cosas, agregado otras, y se han hecho varios resúmenes de diferentes documentos para agregarlos al que se está leyendo en este momento. (En esta primera versión faltan muchas cosas por hacer, las cuales saldrán publicadas en la segunda revisión)

Cosas por hacer

• Agregar mas códigos de ejemplo. • Terminar de traducir algunas cosas que faltan. • Hacer revisiones / correcciones al documento actual.

Nota: las cosas que faltan se muestran en detalle al final de este documento.

Créditos

[Documento fuente principal]

- MySQL AB - e-mail : [email protected] web : http://www.mysql.com

[Primer encargado del proyecto, traducciones, revisiones, páginas man]

- Jorge Jesús Churruca "shock dude" - email : [email protected] - email : [email protected] - web : http://jjch.bahialug.com.ar

[Segundo encargado del proyecto, traducciones, revisiones, código]

- Eduardo Zarate - email : [email protected] - web : [http://www.mysql-hispano.org]

www.detodoprogramacion.com

Page 3: Programacion Aplicaciones MySQL Con C

[Otros colaboradores, traducciones, ideas]

- Luciano Faletti - email: [email protected]

- Lisandro Damian Nicanor Perez Meyer - email: [email protected]

- email: Pablo "Zombie" Odorico - [email protected]

Introducción al API C El código del API C de MySQL es distribuido en la librería mysqlclient que viene en el paquete MySQL, y le permite a los programas en C acceder a bases de datos MySQL.

Resulta extremadamente trivial usar este API, ya que por lo único que el programador debe preocuparse es por conocer "las estructuras" que están creadas dentro de esta librería y por los valores de retorno de algunas otras funciones. Son todas estructuras de las cuales podemos hacer uso (llenarlas / modificarlas) desde programas externos; para más información se le puede echar un vistazo al código fuente de "mysql.h" y mysqlclient. ( El API MySQL provee variables, funciones y estructuras listas para usar o llamar desde otros programas, aunque por ahora lo único que nos interesa es: para qué sirve cada función, y que valores retornan.)

Muchos otras APIs (excepto la del connector/J) usan la librería mysqlclient para comunicarse con el servidor MySQL, esto significa que por ejemplo, se puede tomar ventajas de algunas variables que son usadas por otros clientes ya que éstas son referenciadas desde la librería principal.

El cliente tiene un buffer de comunicación con un tamaño máximo. El tamaño del buffer que está establecido inicialmente (16KB) es automáticamente incrementado al máximo (16M). Como el tamaño de los buffers es incrementado sólo cuando esto se demanda, al incrementar el límite máximo definido no causa que más recursos sean usados. Este control del tamaño es más un control para consultas erróneas y paquetes de comunicación.

El buffer de comunicación debe lo suficientemente grande para contener un sencilla sentencia SQL (para el tráfico cliente-servidor) y una fila de datos devueltos (para el tráfico servidor-cliente). Cada buffer de comunicación de un thread es dinámicamente incrementado para manejar cualquier consulta o fila arriba del límite máximo. Por ejemplo, si se tienen valores BLOB que contienen más de 16M de datos, se debe tener un límite de buffer de comunicación de al menos 16M (en ambos, cliente y servidor). El máximo definido por default para el cliente es de 16M, pero el del servidor es de 1M. Sin embargo, este valor puede ser incrementado al cambiar el valor del parámetro max_allowed_packet cuando se inicia el servidor MySQL.

El servidor MySQL disminuye cada buffer de comunicación a net_buffer_length luego de cada consulta. Para los clientes, el tamaño del buffer asociado con una conexión no es disminuido hasta que la conexión es cerrada, en el momento en que la memoria del cliente es reclamada.

En este documento no se incluye información sobre cómo construir programas que hagan

www.detodoprogramacion.com

Page 4: Programacion Aplicaciones MySQL Con C

uso de hilos (threads), sin embargo, sí se comentará algo sobre la construcción de aplicaciones standalone con el uso de la librería mysqld. Estas aplicaciones incluyen el servidor y el cliente en el mismo programa, por lo que no se comunican con un servidor MySQL externo.

Tipos de datos

Antes de comenzar con la descripción de las funciones, vamos a revisar brevemente algunos de los tipos de datos que forman parte del API C de MySQL, mismos que son usados amplíamente en la creación de programas.

MYSQL

Esta estructura es la más importante y más usada, ya que es la que maneja una conexión a la base de datos. Es usada por casi todas las funciones del API.

MYSQL_RES

Esta estructura representa el resultado de una consulta que retorna filas (SELECT, SHOW, DESCRIBE, EXPLAIN). La información retornada desde una consulta se conoce como el conjunto de resultados (result set).

MYSQL_ROW

Representa una fila de datos. Actualmente es implementada como un arreglo de cadenas. (Sin embargo estas cadenas tienen un tratamiento especial y no deben ser consideradas como cadenas terminadas en null). Las filas son obtenidas al llamar a mysql_fetch_row().

MYSQL_FIELD

Esta estructura contiene información sobre el nombre, tipo y tamaño de un campo. Los valores de los campos no son parte de esta estructura; ellos son contenidos en una estructura MYSQL_ROW. Las estructuras MYSQL_FIELD para cada campo se obtienen al llamar a mysql_fetch_field() repetidamente.

MYSQL_FIELD_OFFSET

Es la representación de un offset dentro de una lista de campos. Un offset es el número de un campo dentro de una fila, comenzando en cero.

my_ulonglong

El tipo usado para el número de filas y por mysql_affected_rows(), mysql_num_rows(), y mysql_insert_id(). Este tipo provee un rango de valores de 0 a 1.84e19. En algunos sistemas, el intentar mostrar un valor del tipo my_ulonglong no funcionará. Para imprimir cada uno de estos valores, se debe convertir a unsigned long y usa el formato %lu de printf.

Por ejemplo:

printf("Número de filas: %lu", (unsigned long) mysql_num_rows(result));

www.detodoprogramacion.com

Page 5: Programacion Aplicaciones MySQL Con C

A continuación se muestra como están definidos los tipos de datos presentados anteriormente, mismos que forman parte del código fuente de MySQL (mysqlclient y mysql.h).

Para ver información mas detallada se recomienda leer todos los ficheros fuente.

MYSQL

Estructura que maneja la conexión a una base de datos.

typedef struct st_mysql{ NET net; /* Parámetros de comunicación */ gptr connector_fd; /* ConectorFd para SSL */ char *host,*user,*passwd,*unix_socket,*server_version,*host_info,*info; char *db; struct charset_info_st *charset; MYSQL_FIELD *fields; MEM_ROOT field_alloc; my_ulonglong affected_rows; my_ulonglong insert_id; my_ulonglong extra_info; /* Usado por mysqlshow */ unsigned long thread_id; /* Id para la conexión en el servidor */ unsigned long packet_length; unsigned int port; unsigned long client_flag,server_capabilities; unsigned int protocol_version; unsigned int field_count; unsigned int server_status; unsigned int server_language; unsigned int warning_count; struct st_mysql_options options; enum mysql_status status; my_bool free_me; my_bool reconnect; /* Se fija a 1 para reconexión automática */

char scramble[SCRAMBLE_LENGTH+1];

my_bool rpl_pivot; struct st_mysql* master, *next_slave;

struct st_mysql* last_used_slave; struct st_mysql* last_used_con;

LIST *stmts; /* Lista de todas las sentencias */ const struct st_mysql_methods *methods; void *thd;} MYSQL;

MYSQL_RES

Estructura que representa el resultado de una consulta que retorna filas.

typedef struct st_mysql_res {

www.detodoprogramacion.com

Page 6: Programacion Aplicaciones MySQL Con C

my_ulonglong row_count; MYSQL_FIELD *fields; MYSQL_DATA *data; MYSQL_ROWS *data_cursor; unsigned long *lengths; /* Longitudes de columnas para la fila */ MYSQL *handle; MEM_ROOT field_alloc; unsigned int field_count, current_field; MYSQL_ROW row; MYSQL_ROW current_row; /* buffer para la fila actual */ my_bool eof; /* Usado por mysql_fetch_row */ const struct st_mysql_methods *methods;} MYSQL_RES;

MYSQL_ROW

La representación de una fila de datos.

typedef char **MYSQL_ROW; /* Regresa datos como un arreglo de cadenas*/

MYSQL_FIELD

Estructura que contiene información de los campos.

typedef struct st_mysql_field { char *name; /* Nombre del campo*/ char *org_name; /* Nombre original del campo, para los alias*/ char *table; /* El nombre de la tabla que contiene este campo*/ char *org_table; /* Nombre orig. de la tabla, si tabla fue un alias */ char *db; /* Base de datos de la tabla */ char *catalog; char *def; /* El valor por default para este campo*/ unsigned long length; /* Ancho del campo*/ unsigned long max_length; unsigned int name_length; unsigned int org_name_length; unsigned int table_length; unsigned int org_table_length; unsigned int db_length; unsigned int catalog_length; unsigned int def_length; unsigned int flags; /* Diferentes banderas para el campo */ unsigned int decimals; /* Número de decimales en el campo */ unsigned int charsetnr; /* Conjunto de caracteres */ enum enum_field_types type; /* Tipo del campo */} MYSQL_FIELD;

El tipo del campo puede ser uno de los siguientes:

Valor Descripción

FIELD_TYPE_TINY campo TINYINT

FIELD_TYPE_SHORT campo SMALLINT

FIELD_TYPE_LONG campo INTEGER

FIELD_TYPE_INT24 campo MEDIUMINT

www.detodoprogramacion.com

Page 7: Programacion Aplicaciones MySQL Con C

FIELD_TYPE_LONGLONG

campo BIGINT

FIELD_TYPE_DECIMAL campo DECIMAL OR NUMERIC

FIELD_TYPE_FLOAT campo FLOAT

FIELD_TYPE_DOUBLE campo DOUBLE or REAL

FIELD_TYPE_TIMESTAMP

campo TIMESTAMP

FIELD_TYPE_DATE campo DATE

FIELD_TYPE_TIME campo TIME

FIELD_TYPE_DATETIME

campo DATETIME

FIELD_TYPE_YEAR campo YEAR

FIELD_TYPE_STRING campo CHAR

FIELD_TYPE_VAR_STRING

campo VARCHAR

FIELD_TYPE_BLOBcampo BLOB o TEXT(usar max_length para determinar la longitud maxima)

FIELD_TYPE_SET campo SET

FIELD_TYPE_ENUM campo ENUM

FIELD_TYPE_NULL campo tipo NULL

FIELD_TYPE_CHAR (obsoleto) usar en su lugar FIELD_TYPE_TINY

Se puede utilizar la macro IS_NUM() para averiguar cuando un campo tiene un tipo numérico. Se pasa el tipo a IS_NUM() y ésta retorna una valor TRUE si el campo es numérico:

if(IS_NUM(field->type)) printf("El campo es numérico");

El valor de las banderas puede tener cero o más del siguiente conjunto de bits:

Valor Descripción

NOT_NULL_FLAG El campo no puede ser NULL

PRI_KEY_FLAG El campo es parte de la clave primaria (primary key)

UNIQUE_KEY_FLAG El campo es parte de una clave única

MULTIPLE_KEY_FLAG El campo es parte de una clave no única

UNSIGNED_FLAG El campo tiene el atributo UNSIGNED

ZEROFILL_FLAG El campo tiene el atributo ZEROFILL

BINARY_FLAG El campo tiene el atributo BINARY

AUTO_INCREMENT_FLAG El campo tiene el atributo AUTO_INCREMENT

www.detodoprogramacion.com

Page 8: Programacion Aplicaciones MySQL Con C

ENUM_FLAG El campo es un ENUM (obsoleto)

SET_FLAG El campo es un SET (obsoleto)

BLOB_FLAG El campo es un BLOB o TEXT (obsoleto)

TIMESTAMP_FLAG El campo es un TIMESTAMP (obsoleto)

El uso de las banderas BLOB_FLAG, ENUM_FLAG, SET_FLAG, y TIMESTAMP_FLAG es obsoleto porque ellas indican el tipo de un campo en vez de un atributo de su tipo. El siguiente ejemplo ilustra un ejemplo típico del uso de las banderas:

if(field->flags & NOT_NULL_FLAG) printf("El campo no puede ser nulo");

MYSQL_FIELD_OFFSET

La representación de un offset dentro de una lista de campos.

typedef unsigned int MYSQL_FIELD_OFFSET; /* offset para el campo actual */

Resumen de funciones del API C

Las funciones disponibles en el API C son resumidas aquí y explicadas en mayor detalle en la siguiente sección.

Función Descripción

mysql_affected_rows()

Devuelve el numero de filas cambiadas/borradas/insertadas por la última sentencia UPDATE, DELETE, o INSERT.

mysql_change_user() Cambia de usuario y base de datos en una conexión abierta.

mysql_character_set_name()

Devuelve el nombre del conjunto de caracteres por default para la conexión.

mysql_close() Cierra la conexión con el servidor.

mysql_connect()Se conecta con un servidor MySQL, ahora esta función es obsoleta, se debería usar mysql_real_connect() en su lugar.

mysql_create_db() Crea una base de datos. Esta función es obsoleta; usar en su lugar el comando CREATE DATABASE.

mysql_drop_db() Borra una base de datos. Esta función es obsoltea; usar en su lugar el comando DROP DATABASE.

mysql_eof() Determina cuando se ha leído la última fila de un conjunto de resultados. Esta función es obsoleta; usar en su lugar mysql_errno() o mysql_error().

mysql_errno() Devuelve el número de error de la función MySQL

www.detodoprogramacion.com

Page 9: Programacion Aplicaciones MySQL Con C

invocada más recientemente.

mysql_error() Devuelve un mensaje de error de la función MySQL invocada más recientemente.

mysql_fetch_field() Devuelve el tipo del siguiente campo en la tabla.

mysql_fetch_fields() Devuelve un arreglo de todos los campos.

mysql_fetch_lengths() Devuelve el largo de todas las columnas de la fila actual.

mysql_fetch_row Recupera la siguiente fila del conjunto de resultados.

mysql_field_seek() Pone el cursor de columna, en una columna especifica.

mysql_field_count() Devuelve el número de columnas para la consulta más reciente.

mysql_field_tell() Devuelve la posición del cursor de campo usado por el último mysql_fetch_field().

mysql_free_result() Libera la memoria usada por un conjunto de resultados.

mysql_get_client_info()

Devuelve la versión del cliente como una cadena.

mysql_get_host_info() Devuelve una cadena que describe la conexión.

mysql_get_version_server()

Devuelve la versión del servidor como un valor entero.

mysql_info() Devuelve información acerca de la consulta ejecutada más recientemente.

mysql_init() Obtiene o inicializa una estructura MYSQL.

mysql_insert_id() Devuelve el ID generado por una columna AUTO_INCREMENT en la consulta previa.

mysql_list_dbs() Devuelve los nombres de las bases de datos que coinciden con una expresión regular sencilla.

mysql_list_fields() Devuelve los nombres de campos que coinciden con una expresión regular sencilla.

mysql_list_processes()

Devuelve una lista de los threads actuales.

mysql_list_tables() Devuelve los nombres de tablas que coinciden con una expresión regular sencilla.

mysql_num_fields() Devuelve el número de columnas en un conjunto de resultados.

mysql_num_rows() Devuelve el número de filas en un conjunto de

www.detodoprogramacion.com

Page 10: Programacion Aplicaciones MySQL Con C

resultados.

mysql_options() Configura opciones de conexión para mysql_connect().

mysql_ping() Permite verificar si la conexión con el servidor está funcionando.

mysql_query() Ejecuta una consulta SQL.

mysql_real_connect() Permite establecer la conexión con el servidor.

mysql_select_db() Selecciona la base de datos sobre la que se ejecutarán las consultas.

mysql_shutdown() Apaga el servidor MySQL.

mysql_stat() Devuelve el status actual del servidor como una cadena.

mysql_store_result() Recupera un conjunto de resultados completamente.

mysql_use_result() Inicia una recuperación fila-por-fila del conjunto de resultados.

Descripción de funciones

En la descripción de las funciones que se hará a continuación, un parámetro con valor de retorno NULL significa null en el sentido de la programación en C , y no un null de SQL/MySQL.

Las funciones que devuelven valores, generalmente devuelven un entero o un puntero, a no ser que esté especificado de otra forma, las funciones que retornan un puntero devuelven un valor no nulo para indicar éxito, o un valor nulo para indicar fracaso y las funciones que retornan un entero devuelven cero para indicar éxito o un valor distinto de cero para indicar fracaso.

Resumiendo:

Una función que devuelve un puntero:

• Valor no NULL = éxito • Valor NULL = fracaso

Una función que devuelve un entero:

• Devuelve 0 = éxito • Devuelve distinto de 0 = fracaso.

www.detodoprogramacion.com

Page 11: Programacion Aplicaciones MySQL Con C

mysql_affected_rows()

my_ulonglong mysql_affected_rows(MYSQL *mysql)

Descripción

Devuelve el número de filas cambiadas por el último UPDATE, eliminadas por el último DELETE o insertadas por el último INSERT. Puede ser llamada inmediatamente después de mysql_query() para sentencias UPDATE, DELETE o INSERT. Para sentencias SELECT, mysql_affected_rows() trabaja como mysql_num_rows().

Valores de retorno

Un entero mayor que cero indica el número de filas afectadas o recuperadas. Cero indica que no se actualizaron registros para una sentencia UPDATE, no hubo filas que coincidieran con la cláusula WHERE en la consulta o que la consulta no ha sido ejecutada aún.

Errores

Ninguno.

Ejemplo

mysql_query(&mysql,"UPDATE productos SET costo=costo*1.25 WHERE grupo=10"); printf("%ld productos actualizados",(long) mysql_affected_rows(&mysql));

mysql_change_user()

my_bool mysql_change_user(MYSQL *mysql, const char *user, const char *password, const char *db)

Descripción

Cambia el usuario y causa que la base de datos especificada por db llegue a ser la base de datos por default en la conexión especificada por mysql. En las subsecuentes consultas, esta base de datos es la default para la referencia a tablas que no incluyen una base de datos explícita.

mysql_chance_user() falla a menos que el usuario conectado pueda ser autenticado o si no tiene permisos para usar la base de datos. En este caso el usuario y la base de datos no son cambiados. El parámetro db puede ser puesto a NULL si no se tiene una base de datos por default.

Valores de retorno

Cero para éxito, y distinto de cero si ocurrió un error.

Errores

• CR_COMMANDS_OUT_OF_SYNC, el comando fue ejecutado en un orden inapropiado.

• CR_SERVER_GONE_ERROR, el servidor MySQL no está disponible. • CR_SERVER_LOST, se perdió la conexión al servidor durante la consulta.

www.detodoprogramacion.com

Page 12: Programacion Aplicaciones MySQL Con C

• CR_UNKNOWN_ERROR, ocurrió un error desconocido. • ER_UNKNOWN_COM_ERROR, el servidor MySQL no tiene implementado el

comando. • ER_ACCESS_DENIED_ERROR, el nombre de usuario o la contraseña son

incorrectas. • ER_BAD_DB_ERROR, la base de datos no existe. • ER_DBACCESS_DENIED_ERROR, el usuario no tiene los privilegios para acceder a

la base de datos. • ER_WRONG_DB_NAME, el nombre de la base de datos es muy grande.

Ejemplo

if (mysql_change_user(&mysql, "usuario", "password", "nueva_base_de_datos")) { fprintf(stderr, "Fallo al cambiar de usuario. Error: %s ", mysql_error(&mysql)); }

mysql_character_set_name()

const char *mysql_character_set_name(MYSQL *mysql)

Descripción

Devuelve el conjunto de caracteres por default para la conexión actual.

Valores de retorno

El conjunto de caracteres por default.

Errores

Ninguno.

Ejemplo

Pendiente.

mysql_close()

void mysql_close(MYSQL *mysql)

Descripción

Cierra una conexión abierta previamente. mysql_close() también libera el espacio ocupado por el manejador de conexión apuntado por mysql si el manejador fue asignado automáticamente por mysql_init() o mysql_connect().

Valores de retorno

Ninguno.

Errores

Ninguno.

Ejemplo

www.detodoprogramacion.com

Page 13: Programacion Aplicaciones MySQL Con C

Pendiente.

mysql_connect()

MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)

Descripción

Trata de establecer una conexión al servidor MySQL. (Es mejor usar mysql_real_connect() en lugar de la función citada, ya que está quedando obsoleta.)

Valores de retorno

Los mismos que mysql_real_connect().

Errores

Los mismos que mysql_real_connect().

Ejemplo

Pendiente.

mysql_create_db()

int mysql_create_db(MYSQL *mysql, const char *db)

Descripción

Crea la base de datos nombrada por el parámetro db. Esta función se está quedando obsoleta, es preferible usar mysql_query para ejecutar una sentencia SQL "CREATE DATABASE".

Valores de retorno

Cero si la base de datos fue creada con éxito. Distinto de cero si ocurrió algún error.

Errores

• CR_COMMANDS_OUT_OF_SYNC, los comandos fueron ejecutados en un orden inapropiado.

• CR_SERVER_GONE_ERROR, el servidor no está disponible. • CR_SERVER_LOST, se perdió la conexión al servidor mientras se ejecutaba la

consulta. • CR_UNKNOWN_ERROR, ocurrió un error desconocido.

Ejemplo

if(mysql_create_db(&mysql, "mi_base_de_datos")) { fprintf(stderr, "Fallo al crear nueva base de datos. Error: %s", mysql_error(&mysql)); }

www.detodoprogramacion.com

Page 14: Programacion Aplicaciones MySQL Con C

mysql_data_seek()

void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset)

Descripción

Busca una fila arbitraria en un conjunto de resultados. El valor offset es el número de una fila y debe estar en el rango de 0 a mysql_num_rows(stmt)-1. Esta función requiere que la estructura MYSQL_RES contenga el resultado completo de la consulta, de esta manera mysql_data_seek() puede ser usado solo en conjunción con mysql_store_result(), y no con mysql_use_result().

Valores de retorno

Ninguno.

Errores

Ninguno.

Ejemplo

Pendiente.

mysql_debug()

void mysql_debug(const char *debug)

Descripción

Hace un DBUG_PUSH con la cadena dada. mysql_debug() usa la librería de depuración Fred Fish. Para usar esta función, se debe compilar la librería cliente con soporte para debugging.

Valores de retorno

Ninguno.

Errores

Ninguno.

Ejemplo La llamada mostrada aquí causa que la librería cliente genere un trace file en el archivo /tmp/client.trace de la máquina cliente.

mysql_debug("d:t:O,/tmp/client.trace");

mysql_drop_db()

int mysql_drop_db(MYSQL *mysql, const char *db)

Descripción

Borra la base de datos nombrada por el parámetro db. Esta función está quedando obsoleta, se recomienda usar mysql_query() para ejecutar una sentencia SQL "DROP DATABASE".

Valores de retorno

Cero si la base de datos fue borrada. Diferente de cero si ocurrió algún error.

www.detodoprogramacion.com

Page 15: Programacion Aplicaciones MySQL Con C

Errores

• CR_COMMANDS_OUT_OF_SYNC, el comando fue ejecutado en un orden inapropiado.

• CR_SERVER_GONE_ERROR, el servidor MySQL no está disponible. • CR_SERVER_LOST, se perdió la conexión al servidor durante la consulta. • CR_UNKNOWN_ERROR, ocurrió un error desconocido.

Ejemplo

if(mysql_drop_db(&mysql, "mi_base_de_datos")) fprintf(stderr, "Fallo al eliminar la base de datos: Error: %s", mysql_error(&mysql));

mysql_eof()

my_bool mysql_eof(MYSQL_RES *result)

Descripción

El uso de esta función está quedando obsoleto, en su lugar pueden ser usadas mysql_errno() o mysql_error(). mysql_eof() determina si la ultima fila de un conjunto de resultados ha sido leída. Si se obtiene un conjunto de resultados desde una llamada exitosa a mysql_store_result(), el cliente recibe el conjunto completo en una sola operación. En este caso, si mysql_fetch_row() regresa un valor NULL significa que el final del conjunto de resultados ha sido alcanzado y ya no es necesario llamar a mysql_eof(). Cuando se usa con mysql_store_result(), mysql_eof() siempre regresa verdadero (true).

Por otra parte, si se usa mysql_use_result() para iniciar la recuperación de un conjunto de resultados, las filas del conjunto son obtenidas desde el servidor una por una cada vez que se llama a mysql_fetch_row(). Debido a que puede ocurrir un error en la conexión durante este proceso, si mysql_fetch_row() regresa un valor NULL, no significa necesariamente que el final del conjunto de resultados se ha alcanzado. En este caso se puede hacer uso de mysql_eof() para determinar lo que sucedió. mysql_eof() regresa un valor distinto de cero si se llego al final del conjunto y cero si ocurrió un error.

Históricamente mysql_eof() antecede a las funciones de error estándar mysql_errno() y mysql_error(). Puesto que estas funciones de error proporcionan la misma información, su uso es preferido sobre mysql_eof(), la cual es ahora desaprobada.

(En efecto, las funciones de error proporcionan mas información, ya que mysql_eof() regresa solo un valor booleano mientras que estas funciones indican una razón para el error cuando este ocurre.)

Valores de retorno

Cero si no ocurre un error. Distinto de cero si el final del conjunto de resultados ha sido alcanzado.

www.detodoprogramacion.com

Page 16: Programacion Aplicaciones MySQL Con C

Errores

Ninguno.

Ejemplo

mysql_query(&mysql,"SELECT * FROM alguna_tabla"); result = mysql_use_result(&mysql); while((row = mysql_fetch_row(result))) { // Hacer algo con los datos } if(!mysql_eof(result)) // mysql_fetch_row() falló debido a un error { fprintf(stderr, "Error: %s", mysql_error(&mysql)); }

Sin embargo, se puede obtener el mismo efectto con las funciones de error estándar de MySQL:

mysql_query(&mysql,"SELECT * FROM alguna_tabla"); result = mysql_use_result(&mysql); while((row = mysql_fetch_row(result))) { // Hacer algo con los datos } if(mysql_errno(&mysql)) // mysql_fetch_row() falló debido a un error { fprintf(stderr, "Error: %s", mysql_error(&mysql)); }

mysql_errno()

unsigned int mysql_errno(MYSQL *mysql)

Descripción

Para la conexión especificada por mysql, mysql_errno() regresa el código de error para la función invocada más recientemente, que puede fallar o ser exitosa. Un valor de retorno igual a cero significa que no ocurrió ningún error. Los números de mensajes de error en el cliente son listados en el archivo de cabecera 'errmsg.h'. Los números de mensajes de error en el servidor son listados en el archivo de cabecera 'mysqld_error.h'.

En la distribución del código fuente de MySQL se puede encontrar una lista completa de los mensajes de error y sus correspondientes números en el archivo 'docs/mysql_error.txt'. Los códigos de error en el servidor también son listados en la sección 10.1 del manual de MySQL.

Notar que algunas funciones como mysql_fetch_row() no fijan mysql_errno() si tienen éxito. Un principio a seguir es que todas las funciones que tienen que pedir información al servidor reiniciarán mysql_errno() si tienen éxito.

www.detodoprogramacion.com

Page 17: Programacion Aplicaciones MySQL Con C

Valores de retorno

Un valor de código de error para la ultima llamada mysql_xxx(), si ésta falla. Cero significa que no ocurrió ningún error.

Errores

Ninguno.

Ejemplo

Pendiente.

mysql_error()

char *mysql_error(MYSQL *mysql)

Descripción

Para la conexión especificada por mysql, mysql_error() regresa una cadena terminada en nulo (null) conteniendo el mensaje de error para la función invocada más recientemente que falló. Si una función no falla, el valor de retorno de mysql_error() puede ser el error previo o una cadena vacía para indicar que no hubo error. Un principio a seguir es que todas las funciones que tienen que pedir información al servidor reiniciarán mysql_error() si tienen éxito. Para funciones que reinician mysql_errno(), las siguientes dos pruebas son equivalentes:

if(mysql_errno(&mysql)) { // ocurrió un error } if(mysql_error(&mysql)[0] != '0') { // ocurrió un error }

El lenguaje de los mensajes de error en el cliente puede ser cambiado recompilando la librería cliente de MySQL. Actualmente se pueden elegir los mensajes de error en diferentes lenguajes. Valores de retorno

Una cadena terminada en nulo (null) que describe el error. Una cadena vacía si no ocurrió un error.

Errores

Ninguno.

Ejemplo

Pendiente.

mysql_fetch_field()

MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)

Descripción

www.detodoprogramacion.com

Page 18: Programacion Aplicaciones MySQL Con C

Devuelve la definición de una columna de un conjunto de resultados como una estructura MYSQ_FIELD. Se llama a esta función repetidamente para extraer información de todas las columnas en el conjunto de resultados. mysql_fetch_field() devuelve NULL cuando no quedan mas campos.

Valores de retorno

La estructura MYSQL_FIELD para la columna actual. NULL si no hay más columnas.

Errores

Ninguno.

Ejemplo

MYSQL_FIELD *field; while((field = mysql_fetch_field(result))) { printf("Nombre del campo %s", field->name); }

mysql_fetch_fields()

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)

Descripción

Devuelve un arreglo de todas las estructuras MYSQL_FIELD de un conjunto de resultados. Cada estructura provee la definición del campo de una columna del conjunto de resultados.

Valores de retorno

Un arreglo de estructuras MYSQL_FIELD para todas las columnas de un conjunto de resultados.

Errores

Ninguno.

Ejemplo

unsigned int num_fields; unsigned int i; MYSQL_FIELD *fields; num_fields = mysql_num_fields(result); fields = mysql_fetch_fields(result); for(i = 0; i < num_fields; i++) { printf("Campo %u es %s", i, fields[i].name); }

mysql_fetch_field_direct()

MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)

Descripción

Dado el número fieldnr de una columna dentro del conjunto de resultados, devuelve la definición de campo de esa columna como una estructura MYSQL_FIELD. Se puede usar

www.detodoprogramacion.com

Page 19: Programacion Aplicaciones MySQL Con C

esta función para conseguir la definición de una columna arbitraria. El valor del campo debe estar en el rango de 0 a mysql_num_fields(result)-1.

Valores de retorno

La estructura MYSQL_FIELD para la columna especificada.

Errores

Ninguno.

Ejemplo

unsigned int num_fields; unsigned int i; MYSQL_FIELD *field; num_fields = mysql_num_fields(result); for(i = 0; i < num_fields; i++) { field = mysql_fetch_field_direct(result, i); printf("Campo %u es %s", i, field->name); }

mysql_fetch_lengths()

unsigned long *mysql_fetch_lengths(MYSQL_RES *result)

Descripción

Devuelve las longitudes de las columnas de la fila actual dentro de un conjunto de resultados. Si se planea copiar los valores de campo, esta información de longitud es también útil para optimización, ya que puede evitar llamar a strlen(). Además, si el conjunto de resultados contiene datos binarios, se debe usar esta función para determinar el tamaño de los datos, ya que strlen() devuelve resultados incorrectos para cualquier campo que contenga caracteres nulos (null).

Valores de retorno

Un arreglo de enteros unsigned long representando el tamaño de cada columna (sin incluir ningún caracter terminado en null). NULL si ocurre algún error.

Errores

mysql_fetch_lengths() es válido solo para la fila actual del conjunto de resultados. Retorna NULL si es llamado antes de llamar mysql_fetch_row() o después de buscar todas las filas en el resultado.

Ejemplo

MYSQL_ROW row; unsigned long *lengths; unsigned int num_fields; unsigned int i; row = mysql_fetch_row(result); if (row) { num_fields = mysql_num_fields(result); lengths = mysql_fetch_lengths(result); for(i = 0; i < num_fields; i++)

www.detodoprogramacion.com

Page 20: Programacion Aplicaciones MySQL Con C

{ printf("Columna %u es %lu bytes en longitud.", i, lengths[i]); } }

mysql_fetch_row()

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

Descripción

Recupera la siguiente fila de un conjunto de resultados. Cuando es usado después de mysql_store_result(), mysql_fetch_row() devuelve NULL cuando no hay más filas que leer. Cuando es usado después de mysql_use_result(), mysql_fetch_row() devuelve NULL cuando no hay más filas que recuperar o si ocurre algún error. El número de valores en la fila es dado por mysql_num_fields(result). Si row contiene el valor de devuelto por mysql_fetch_row(), los punteros a los valores son accedidos como row[0] hasta row[mysql_num_fields(result)-1]. Valores NULL en la fila son indicados por punteros NULL. Las longitudes de los valores de los campos en la fila pueden ser obtenidos llamando a mysql_fetch_lengths(). Campos vacíos y campos que contegan NULL tienen longitud 0; se les puede distinguir checando el puntero para el valor del campo. Si el puntero es NULL, el campo es NULL; de otra forma, el campo esta vacío.

Valores de retorno

Una estructura MYSQL_ROW para la siguiente fila. NULL si no hay más filas que recuperar o si ha ocurrido un error.

Errores

• CR_SERVER_LOST, se perdió la conexión al servidor durante la consulta. • CR_UNKNOWN_ERROR, ocurrió un error desconocido.

Ejemplo

MYSQL_ROW row; unsigned int num_fields; unsigned int i;

num_fields = mysql_num_fields(result); while ((row = mysql_fetch_row(result))) { unsigned long *lengths; lengths = mysql_fetch_lengths(result); for(i = 0; i < num_fields; i++) { printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL"); } printf("n"); }

mysql_field_count()

unsigned int mysql_field_count(MYSQL *mysql)

www.detodoprogramacion.com

Page 21: Programacion Aplicaciones MySQL Con C

Si se está usando una versión de MySQL anterior a la 3.22.24, se deberá usar en cambio:

unsigned int mysql_num_fields(MYSQL *mysql).

Descripción

Devuelve el número de columnas para la consulta más reciente en la conexión mysql. El uso normal de esta función es cuando mysql_store_result() devuelve NULL (y por lo tanto no se tiene un puntero al conjunto resultados). En este caso, se puede llamar a mysql_field_count() para determinar si mysql_store_result() debía haber producido un resultado no vacío. Esto permite al programa cliente tomar la acción adecuada sin saber si la consulta fue una sentencia SELECT (o del tipo SELECT).

Valores de retorno

Un entero unsigned representando el número de campos en un conjunto de resultados.

Errores

Ninguno.

Ejemplo

MYSQL_RES *result; unsigned int num_fields; unsigned int num_rows; if (mysql_query(&mysql,query_string)) { // error } else // la consulta fue exitosa, se procesan los datos{ result = mysql_store_result(&mysql); if (result) // hay filas { num_fields = mysql_num_fields(result); // recuperar las filas y entonces llamar a mysql_free_result(result) } else // mysql_store_result() no regresó nada, debía ser así? { if(mysql_field_count(&mysql) == 0) { // la consulta no regresó datos // (ésta no fue una consulta SELECT) num_rows = mysql_affected_rows(&mysql); } else // mysql_store_result() debe tener los datos regresados { fprintf(stderr, "Error: %s", mysql_error(&mysql)); } } }

Una alternativa es reemplazar la llamada mysql_field_count(&mysql) con mysql_errno(&mysql). En este caso, se esta checando directamente por un error de mysql_store_result() más que infiriendo del valor de mysql_field_count() si la sentencia fue un SELECT.

www.detodoprogramacion.com

Page 22: Programacion Aplicaciones MySQL Con C

mysql_init()

MYSQL *mysql_init(MYSQL *mysql)

Descripción

Asigna o inicializa un objeto MYSQL adecuado para mysql_real_connect(). Si mysql es un puntero NULL la función asigna, inicializa y devuelve un nuevo objeto. De otra manera el objeto es inicializado y la dirección de dicho objeto es regresada. Si mysql_init() asigna un nuevo objeto, éste será liberado cuando mysql_close() sea llamada para cerrar la conexión.

Valores de retorno

Un manejador MYSQL* inicializado. NULL si la memoria es insuficiente para asignar un nuevo objeto.

Errores

• En caso de memoria insuficiente se devuelve NULL.

Ejemplo

Pendiente

mysql_kill()

int mysql_kill(MYSQL *mysql, unsigned long pid)

Descripción

Le pide al servidor que mate el hilo (thread) especificado por pid.

Valores de retorno

Cero en caso de éxito. Distinto de cero si ocurrió algún error.

Errores

• CR_COMMANDS_OUT_OF_SYNC, el comando fue ejecutado en un orden inapropiado.

• CR_SERVER_GONE_ERROR, el servidor MySQL no está disponible. • CR_SERVER_LOST, se perdió la conexión al servidor durante la consulta. • CR_UNKNOWN_ERROR, ocurrió un error desconocido.

Ejemplo

Pediente.

mysql_num_rows()

my_ulonglong mysql_num_rows(MYSQL_RES *result)

Descripción

Devuelve el número de filas en un conjunto de resultados.

www.detodoprogramacion.com

Page 23: Programacion Aplicaciones MySQL Con C

El uso de mysql_num_rows() depende del uso de mysql_store_result() o mysql_use_result() para obtener el conjunto de resultados. Si se utiliza mysql_store_result(), mysql_num_rows() puede ser llamada inmediatamente. Si se usa mysql_store_result(), mysql_num_rows() no regresará el valor correcto hasta que todas las filas en el conjunto de resultados hayan sido recuperadas.

Valores de retorno

El número de filas en el conjunto de resultados.

Errores

Ninguno.

Ejemplo

Pendiente.

mysql_query()

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

Descripción

Ejecuta la consulta SQL especificada por la cadena query. La consulta debe consistir de una sentencia SQL sencilla, y no se debe agregar el punto y coma (;) al final de la sentencia.

mysql_query() no puede ser usada por consultas que contengan datos binarios; en su lugar debe ser usada la función mysql_real_query().

Si se desea conocer si la consulta debe regresar un conjunto de resultados o no, se puede usar mysql_field_count() para checar esto.

Valores de retorno

Cero si la consulta fue exitosa. Distinto de cero si ocurrió un error.

Errores

• CR_COMMANDS_OUT_OF_SYNC, el comando fue ejecutado en un orden inapropiado.

• CR_SERVER_GONE_ERROR, el servidor MySQL no está disponible. • CR_SERVER_LOST, se perdió la conexión al servidor durante la consulta. • CR_UNKNOWN_ERROR, ocurrió un error desconocido.

Ejemplo

Pendiente.

mysql_real_connect()

MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port,

www.detodoprogramacion.com

Page 24: Programacion Aplicaciones MySQL Con C

const char *unix_socket, unsigned long client_flag)

Descripción

mysql_real_connect() intenta establecer una conexión con al servidor de bases de datos MYSQL corriendo en un host. mysql_real_connect() debe completarse exitosamente antes de poder ejecutar cualquier otra función, con la excepción de mysql_client_info(). Los parámetros son especificados como sigue:

• El primer parámetro debe ser la dirección de una estructura MYSQL existente. Antes de llamar a mysql_real_connect() es necesario llamar a mysql_init() para inicializar la estructura MYSQL. También se pueden cambiar varias opciones de conexión con la llamada de mysql_options().

• El valor de host puede un hostname o una dirección IP. Si host es NULL o la cadena "localhost", entonces se asume la conexión con el host local. Si el sistema soporta sockets (Unix) o pipes (Windows) éstos son usados en vez de TCP/IP para conectarse al servidor.

• El parámetro user contiene el login para usuarios de MySQL. Si user es NULL o la cadena vacía "", el usuario actual es asumido. Bajo Unix, este es el login actual. Bajo otros sistemas es diferente.

• El parámetro passwd contiene el password de usuario. Si passwd es NULL, sólo serán checadas las entradas en la tabla user que tengan un password vacío.

• El parámetro db es el nombre de la base de datos. Si db no es NULL, la conexión pondrá la base de datos default a este valor.

• Si port no es 0 (cero), dicho valor será usado como número de puerto para conexiones TCP/IP. Notar que el parámetro host determina el tipo de la conexión.

Valores de retorno

Un manejador de conexión a MYSQL* si la conexión fue realizada con éxito, y NULL si la conexión falló. En una conexión exitosa, el valor de retorno es igual al valor del primer parámetro.

Errores

• CR_CONN_HOST_ERROR, fallo al conectarse al servidor MySQL. • CR_CONNECTION_ERROR, fallo al conectarse al servidor MySQL local. • CR_IPSOCK_ERROR, fallo al crear un socket IP. • CR_OUT_OF_MEMORY, fuera de memoria. • CR_SOCKET_CREATE_ERROR, fallo al crear un socket Unix. • CR_UNKNOWN_HOST, fallo al localizar la dirección IP del host. • CR_VERSION_ERROR, una incompatibilidad de protocolos resultó al intentar

conectarse al servidor con una librería cliente que usar una versión de protocolo diferente.

• CR_NAMEDPIPEOPEN_ERROR, fallo al crear un pipe en Windows. • CR_NAMEDPIPEWAIT_ERROR, fallo al esperar un pipe en Windows. • CR_NAMEDPIPESETSTATE_ERROR, fallo al obtener un pipe en Windows.

Ejemplo

MYSQL mysql; mysql_init(&mysql);

www.detodoprogramacion.com

Page 25: Programacion Aplicaciones MySQL Con C

mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name"); if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) { fprintf(stderr, "Fallo al establecer la conexión: Error: %s", mysql_error(&mysql)); }

mysql_store_result()

MYSQL_RES *mysql_store_result(MYSQL *mysql)

Descripción

Se debe llamar a mysql_store_result() o mysql_use_result() para cada consulta (SELECT, SHOW, DESCRIBE, EXPLAIN) que recupere datos de manera exitosa.

No se tiene que llamar a mysql_store_result() o mysql_use_result() para otras consultas, sin embargo no hay notables problemas de eficiencia si se llama a mysql_store_result() en todos los casos.

Si de desea conocer si la consulta debe regresar un conjunto de resultados o no, se puede usar mysql_field_count() para averiguar esto.

mysql_store_result() lee el resultado completo de la consulta y lo guarda en el cliente en una estructura MYSQL_RES.

mysql_store_result() devuelve un puntero nulo si la consulta no devuelve un conjunto de resultados (si la consulta fue, por ejemplo, un sentencia INSERT).

mysql_store_result() también devuelve un puntero nulo si falla la lectura del conjunto de resultados. En este caso, se recomienda el uso de mysql_error() para averiguar que es lo que falló.

Un conjunto de resultados vacío es regresado si la consulta no devuelve filas. (Un conjunto de resultados vacío difiere de un puntero nulo)

Una vez que se ha llamado a mysql_store_result() y se obtiene un conjunto de resultados que no es un puntero nulo, se puede llamar a mysql_num_rows() para determinar cuántas filas hay en el conjunto de resultados.

Se puede llamar a mysql_fetch_row() para ir leyendo las filas del conjunto de resultados, o mysql_row_seek() y mysql_row_tell() para obtener o fijar la posición de la fila actual dentro del conjunto de resultados. Se debe llamar a mysql_free_result() una vez que ya no se usará

www.detodoprogramacion.com

Page 26: Programacion Aplicaciones MySQL Con C

el conjunto de resultados.

Valores de retorno

Una estructura MYSQL_RES con los resultados. NULL si ocurrió un error.

Errores

• CR_COMMANDS_OUT_OF_SYNC, el comando fue ejecutado en un orden inapropiado.

• CR_OUT_OF_MEMORY, fuera de memoria. • CR_SERVER_GONE_ERROR, el servidor MySQL no está disponible. • CR_SERVER_LOST, se perdió la conexión al servidor durante la consulta. • CR_UNKNOWN_ERROR, ocurrió un error desconocido.

Ejemplo

Pendiente.

mysql_use_result()

MYSQL_RES *mysql_use_result(MYSQL *mysql)

Descripción

Se debe llamar a mysql_store_result() o mysql_use_result() para cada consulta (SELECT, SHOW, DESCRIBE, EXPLAIN) que recupere datos de manera exitosa.

mysql_use_result() inicializa la recuperación de un conjunto de resultados pero no lee el conjunto de resultados como lo hace mysql_store_result(). En este caso, cada fila es recuperada individualmente al hacer llamadas a mysql_fetch_row(). Esta función lee los resultados de una consulta directamente desde el servidor, sin la necesidad de almacenar los resultados en el cliente, por lo que utiliza mucho menos memoria que mysql_store_result(). El cliente asigna memoria únicamente para la fila actual y un buffer de comunicación que puede ser hasta de max_allowed_packet bytes.

Por el otro lado, no se debe usar mysql_use_result() si se está haciendo mucho procesamiento de las filas en el lado del cliente.

Cuando se use mysql_use_result(), se debe ejecutar mysql_fetch_row() hasta que se devuelva un valor NULL, de lo contrario, la filas no recuperadas serán devueltas como parte del conjunto de resultados en la siguiente consulta.

No se puede usar mysql_data_seek(), mysql_row_seek(), mysql_row_tell(), mysql_num_rows() o mysql_affected_rows() con se maneja un conjunto de resultados con mysql_use_result(), sin embargo, una vez que se han recuperado todas las filas, mysql_num_rows() sí devuelve el total de filas.

www.detodoprogramacion.com

Page 27: Programacion Aplicaciones MySQL Con C

Se debe llamar a mysql_free_result() una vez que ya no se usará el conjunto de resultados.

Valores de retorno

Una estructura MYSQL_RES. NULL si ocurrió un error.

Errores

• CR_COMMANDS_OUT_OF_SYNC, el comando fue ejecutado en un orden inapropiado.

• CR_OUT_OF_MEMORY, fuera de memoria. • CR_SERVER_GONE_ERROR, el servidor MySQL no está disponible. • CR_SERVER_LOST, se perdió la conexión al servidor durante la consulta. • CR_UNKNOWN_ERROR, ocurrió un error desconocido.

Ejemplo

Pendiente.

Creación de programas cliente

A continuación se presenta un breve ejemplo sobre el uso del API C de MySQL. Este programa de ejemplo debería de poder ser compilado y ejecutado en cualquier distribución de Linux.

Para el ejemplo que se va a mostrar, se usará la siguiente base de datos de prueba.

mysql> CREATE DATABASE dbtest;Query OK, 1 row affected (0.00 sec)

mysql> use dbtest;Database changed

mysql> CREATE TABLE tbltest(id int not null auto_increment, -> datos varchar(255) default null, -> primary key(id));Query OK, 0 rows affected (0.08 sec)

mysql> GRANT ALL ON dbtest.* TO dbusr@localhost IDENTIFIED BY "dbpwd";Query OK, 0 rows affected (0.05 sec)

Establecer la conexión

Antes de poder mandar algún tipo de consulta al servidor, es necesario tener disponible una conexión a la base de datos.

Para establecer la conexión a un servidor MySQL, se puede utilizar la función mysql_connect(), o mysql_real_connect(), sin embargo, dado que el uso de mysql_connect() está quedando obsoleto, se recomienda el uso de mysql_real_connect().

www.detodoprogramacion.com

Page 28: Programacion Aplicaciones MySQL Con C

Al intentar establecer la conexión, es necesario llamar a la función mysql_init() para inicializar un manejador de conexión y posteriormente llamar a la función mysql_real_connect() con dicho manejador (junto con otra otro información tal como el servidor, el nombre de usuario, y la contraseña).

MYSQL mysql;mysql_init(&mysql);

if (!mysql_real_connect(&mysql,"localhost","dbusr","dbpwd","dbtest",0,NULL,0)){ printf("Falló en la conexión a la base de datos, Error: %s\n", mysql_error(&mysql));}

En este momento la función mysql_real_connect() pone la bandera "reconnect" (parte de la estructura MYSQL) a un valor 1. Esta bandera indica que en el caso de que una consulta no pueda ser ejecutada debido a que se perdió de la conexión, se intentará volver a establecer la conexión al servidor antes de cancelar la ejecución de la consulta. Cuando ya no se utilice una conexión, se llama a la función mysql_close() para destruirla.

Para detectar y reportar errores, MySQL proporciona acceso a la información de los errores por medio de las funciones mysql_errno() y mysql_error(). Éstas regresan el código del error o el mensaje de error para la función invocada más recientemente, permitiendo determinar cuando ocurrió un error y cual fue.

Ejecución de sentencias

Mientras una conexión esté activa, el cliente puede enviar sentencias SQL al servidor usando la función mysql_query().

Esta función toma como parámetros la conexión a la base de datos, y la consulta que se quiere realizar. En caso de éxito, se retorna un valor cero. En el caso especial que se necesiten insertar datos binarios (los cuales puede incluir bytes nulos), se debe usar una función relacionada llamada mysql_real_query(). Para el ejemplo que será presentado aquí, se hará uso de mysql_query().

Nota: las consultas que se envian no deben terminar en punto y coma.

Sentencias SQL que no devuelven datos

Las sentencias no SELECT (INSERT, DELETE y UPDATE) son sentencias que no devuelven datos, y por lo tanto son más sencillas de usar.

Para cada consulta de este tipo se puede averiguar cuántas filas fueron cambiadas (o bien

www.detodoprogramacion.com

Page 29: Programacion Aplicaciones MySQL Con C

afectadas) al llamar a la función mysql_affected_rows().

mysql_query(&mysql, "INSERT INTO tbltest VALUES(0,'Dato de prueba A')");

if(mysql_affected_rows(&mysql) > 0) printf("%lu registro insertado. ", (unsigned long)mysql_affected_rows(&mysql));else printf("Fallo al insertar el registro, Error: %s", mysql_error(&mysql));

Por razones de portabilidad, la función mysql_affected_rows() devuelve un valor especial que representa un entero sin signo. Para usar la función printf(), se recomienda que se haga un cast a unsigned long, con un especificación de formato %lu.

Antes de insertar datos en una base de datos generalmente se deben escapar todos los caracteres especiales, esto es, aquellos caracteres que para MySQL tienen un significado especial. La función mysql_real_escape_string() es usada para este propósito. Esta función toma como parámetros un objeto MYSQL, un buffer para almacenar los datos codificados, los datos originales, y la longitud de los datos originales. Al usar esta función debemos asegurarnos de que el buffer sea del doble de tamaño que los datos originales, con un byte extra para el caracter NULL al final de la cadena.

Sentencias que devuelven datos

Para leer los registros de una base de datos se envia una sentencia SELECT también con el uso de la función mysql_query().

Para consultas SELECT, se obtienen las filas seleccionadas como un conjunto de resultados. (Notar que algunas sentencias son similares a un SELECT en el sentido de que también devuelven filas. Estas incluyen SHOW, DESCRIBE, y EXPLAIN, y deben ser tratadas de la misma manera que una sentencia SELECT).

Hay dos formas en las que un cliente puede procesar un conjunto de resultados. Una de ellas es recuperar en el momento el conjunto de resultados completo al llamar a la función mysql_store_result(). Esta función obtiene desde el servidor todas las filas regresadas por la consulta y los almacena en el cliente. La segunda forma es que el cliente recupere fila por fila del conjunto de resultados al llamar a la función mysql_use_result(). Esta función inicializa la recuperación de los datos, pero realmente no obtiene ninguna fila desde el servidor.

En ambos casos, el acceso a las filas se hace con la función mysql_fetch_row(). Con mysql_store_result(), mysql_fetch_row() accede las filas que ya han sido recuperadas desde el servidor. Con mysql_use_result(), mysql_fetch_row() recupera solo una fila desde el servidor. La información acerca del tamaño de los datos en cada fila esta disponible al llamar a la función mysql_fetch_lengths().

www.detodoprogramacion.com

Page 30: Programacion Aplicaciones MySQL Con C

mysql_query(&conn, "SELECT * FROM tbltest"); res = mysql_store_result(&conn);

for(i=0; i< mysql_num_rows(res); i++) { row = mysql_fetch_row(res); printf("%s %s n", row[0], row[1]); } mysql_free_result(res);

Después de que se ha trabajado con el conjunto de resultados, se llama a la función mysql_free_result() para liberar la memoria usada por este. Los dos mecanismos de recuperación son complementarios. Los programas cliente deben elegir el enfoque que sea mas apropiado para sus requerimientos. En la practica, los programas cliente usan mysql_store_result() mas comúnmente. Una ventaja de usar mysql_store_result() es que debido a que todas las filas han sido recuperadas por el cliente, no solo se pueden acceder a ellas secuencialmente, es decir, se pueden acceder las filas hacia adelante y hacia atrás en el conjunto de resultados usando mysql_data_seek() o mysql_row_seek() para cambiar la posición de la fila actual dentro del conjunto de resultados.

También se puede averiguar cuantas filas existen al llamar a la función mysql_num_rows(). Por otra parte, los requerimientos de memoria al usar mysql_store_result() pueden ser muy altos para conjuntos de resultados muy grandes y se pueden encontrar condiciones de falta-de-memoria.

Una ventaja de usar mysql_use_result() es que el cliente requiere menos memoria porque este mantiene únicamente una fila a la vez. Las desventajas son que se tiene que procesar cada fila rápidamente para evitar conflictos en el servidor, no se tiene acceso aleatorio dentro del conjunto de resultados (las filas se pueden acceder solo secuencialmente), y no se puede conocer cuantas filas hay en el conjunto de resultados hasta que se recuperen todas las filas. Además, se tienen que recuperar todas las filas aun si a la mitad del conjunto de resultados se determina que se ha encontrado la información que se estaba buscando.

El API hace posible que los clientes respondan apropiadamente a consultas (recuperando filas sólo cuando sea necesario) sin conocer cuando la consulta es o no un SELECT. Se puede hacer esto al llamar a mysql_store_result() después de cada mysql_query() ( o mysql_real_query()). Si la llamada al conjunto de resultados sucede, la consulta fue un SELECT y se pueden leer las filas.

Si la llamada al conjunto de resultados falla, se puede llamar a la función mysql_field_count() para determinar cuando un resultado fue el esperado. Si mysql_field_count() regresa cero, la consulta no regreso datos (lo que indica que fue un INSERT, UPDATE, DELETE, etc.), y no se esperaba que regresaran filas. Si mysql_field_count() es distinto de cero, la consulta debió regresar filas, pero no lo hizo. Lo que indica que la consulta fue un SELECT que fallo. Revisar la descripción de la función mysql_field_count() para ver un ejemplo de como puede ser utilizada.

www.detodoprogramacion.com

Page 31: Programacion Aplicaciones MySQL Con C

Ambos mysql_store_result() y mysql_use_result() permiten obtener información acerca de los campos que componen el conjunto de resultados (el número de campos, sus nombres y tipos, etc). Se puede acceder la información de los campos secuencialmente dentro de la fila al llamar a la función mysql_fetch_field() repetidamente, o por el número de campo dentro de la fila al llamar a la función mysql_fetch_field_direct(). La posición actual del cursor en el campo puede ser cambiada al llamar a mysql_field_seek(). Al fijar el cursor en el campo se afectan las subsecuentes llamadas a mysql_fetch_field(). También se puede obtener la información de todos los campos a la vez al llamar a la función mysql_fetch_fields().

Ejemplo completo

#include <stdlib.h> #include <mysql.h> int main (int argc, char *argv[]) { MYSQL mysql; MYSQL_ROW row; MYSQL_RES *res; char *query; int i=0; mysql_init(&mysql); if (!mysql_real_connect(&mysql,"localhost","dbusr","dbpwd","dbtest",0,NULL,0)) { printf("Fallo en la conexión a la base de datos, Error: %s\n", mysql_error(&mysql)); } else { printf("Conexión a la base de datos establecida... \n"); query = malloc(strlen(argv[1]) + 255); sprintf(query, "INSERT INTO tbltest VALUES(0,'%s')", argv[1]); mysql_query(&mysql, query); if(mysql_affected_rows(&mysql) > 0) printf("%lu registro insertado. \n", (unsigned long)mysql_affected_rows(&mysql)); else printf("Fallo al insertar el registro, Error: %s \n", mysql_error(&mysql)); mysql_query(&mysql, "SELECT * FROM tbltest"); res = mysql_store_result(&mysql); for(i=0; i< mysql_num_rows(res); i++)

www.detodoprogramacion.com

Page 32: Programacion Aplicaciones MySQL Con C

{ row = mysql_fetch_row(res); printf("%s \t\t %s \n", row[0], row[1]); } mysql_free_result(res); mysql_close(&mysql); } return 0; }

Compilación

Todos los programas que accedan a bases de datos MySQL deben incluir el archivo de cabecera mysql.h, y al momento de la compilación deben ser enlazados con la librería mysqlclient, al agregar las opciones "-libmysqlclient -lz ".

Si no se encuentran las librerías, es muy probable que se tenga que especificar la ruta a ellas (ej: -L/usr/local/lib, -L/usr/local/mysql/lib, etc.)

De manera similar, si no se encuentran los archivos de cabecera de MySQL, se deberá especificar la ruta a ellos (ej: -I/usr/local/include, -I/usr/local/mysql/include, etc.)

En este caso se tiene instalado MySQL 4 en el directorio /usr/local/mysql. La compilación queda de la siguiente manera:

gcc -o test test.c -I/usr/local/mysql/include -L/usr/local/mysql/lib -lmysqlclient -lz

Manejando ejecución de múltiples consultas

Desde la versión 4.1 MySQL soporta la ejecución de múltiples sentencias especificadas en una sola consulta. Para usar esta capacidad en una conexión dada, se necesita especificar la opción CLIENT_MULTI_QUERIES en los parámetros de mysql_real_connect() cuando se abre la conexión. Se puede también fijar el valor para una conexión al llamar mysql_set_server_option(MYSQL_OPTION_MULTI_STATEMENTS_ON).

Por defecto mysql_query() y mysql_real_query() devuelven solamente el primer status de la consulta y los siguientes status se pueden procesar usando mysql_more_results() y mysql_nex_results().

Ejemplo

/* Conecta al servidor con la opción CLIENT_MULTI_QUERIES */ mysql_real_connect(..., CLIENT_MULTI_QUERIES);

/* ejecuta varias consultas */

www.detodoprogramacion.com

Page 33: Programacion Aplicaciones MySQL Con C

mysql_query(mysql,"DROP TABLE IF EXISTS test_table; CREATE TABLE test_table(id INT); INSERT INTO test_table VALUES(10); UPDATE test_table SET id=20 WHERE id=10; SELECT * FROM test_table; DROP TABLE test_table";

do{ /* Procesa todos los resultados */ ... printf("Total de filas afectadas: %lld", mysql_affected_rows(mysql)); ... if (!(result= mysql_store_result(mysql))) { printf(stderr, "Error al procesar la consulta.\n"); exit(1); } process_result_set(result); /* función cliente */ mysql_free_result(result);} while (!mysql_next_result(mysql));

Servidor embebido (embedded server)

Nota: ahora ya no se está hablando de la librería mysqlclient sino de la librería mysqld.

Se necesitan las siguientes funciones para permitir a las aplicaciones ser enlazadas a las librerías del servidor MySQL embebido (embedded server). Si el programa es enlazado con –libmysqlclient en lugar de –lmysqld, estas funciones no hacen nada. Esto hace posible elegir entre usar el servidor embebido y un servidor stand-alone sin hacer ninguna modificación de código.

mysql_server_init()

int mysql_server_init(int argc, char **argv, char **groups)

Descripción

La función necesita ser llamada una vez en el programa usando el servidor embebido antes de llamar a ninguna otra función. Esto arranca el servidor e inicializa cualquier otro subsistema (mysys, InnoDB, etc) que use el servidor. Si esta función no es llamada el programa fallará.

Los argumentos argc y argv son análogos a los argumentos de main(). El primer elemento de argv es ignorado (por lo general contiene el nombre del programa). Por conveniencia, argc puede ser 0 (cero) si no hay argumentos de línea de comandos para el servidor. mysql_server_init() hace una copia de los argumentos así que se puede destruir argv o groups de manera segura después de la llamada mysql_server_init().

Valores de retorno

www.detodoprogramacion.com

Page 34: Programacion Aplicaciones MySQL Con C

0 si está todo bien, 1 si ocurrió un error.

Ejemplo

#include #include static char *server_args[] = { "this_program", /* Esta cadena no es usada */ "--datadir=.", "--key_buffer_size=32M" }; static char *server_groups[] = { "embedded", "server", "this_program_SERVER", (char *)NULL }; int main(void) { mysql_server_init(sizeof(server_args) / sizeof(char *), server_args, server_groups); /* Usar aquí cualquier función del API MySQL */ mysql_server_end(); return EXIT_SUCCESS; }

mysql_server_end()

void mysql_server_end(void)

Descripción

Esta función necesita ser llamada una vez en el programa después de todas las otras funciones. Esta función propiamente dicha sirve para apagar el servidor.

Valores de retorno

Ninguno.

Por hacer ...

Falta mucho por hacer, desde correcciones, ejemplos de código y resúmenes, hasta una última parte de la traducción de la guía oficial (la cual se encuentra en el directorio Docs/manual_toc.html del paquete MySQL). Si estás interesado en participar o enviar cualquier tipo de ayuda, por favor contáctate con nosotros.

Actualmente estamos trabajando en las siguientes secciones:

• 9.1.4 C API Prepared Statements • 9.1.5 C API Prepared Statement Datatypes • 9.1.6 C API Prepared Statement Function Overview • 9.1.7 C API Prepared Statement Function Descriptions • 9.1.9 C API Handling of Date and Time Values • 9.1.10 C API Threaded Function Descriptions

www.detodoprogramacion.com