Sentencias preparadas de MySQL en C (ejemplo completo)


MySql logo

En el trabajo me tocó hacer una interfaz a una base de datos MySQL desde C puro, y buscando en Internet di con el libro de MySQL Developer’s Library de Paul DuBois el cual tiene un ejemplo muy bueno de cómo hacer sentencias preparadas usando el conector de C de MySQL en el capítulo 7. Y aunque en el libro explica como ejecutar una sentencia SQL teniendo parámetros preparados (preapared statements) para luego explicar como obtener los datos de la consulta, al final no se ve todo en conjunto por lo que me dispuse a colocar un ejemplo completo:

void iodb_getNumAddresses(int id, int *numAddresses){

 MYSQL *conn;
 MYSQL_STMT *stmt;
 char *sql;

 // Bind variables
 MYSQL_BIND param[1], result[1];

 int myId, myNumAddresses;
 my_bool is_null[1];

 sql = "select count(*) from addresses where id = ?";

 // Open Database
 openDB(&conn);

 // Allocate statement handler
 stmt = mysql_stmt_init(conn);

 if (stmt == NULL) {
  print_error(conn, "Could not initialize statement handler");
  return;
 }

 // Prepare the statement
 if (mysql_stmt_prepare(stmt, sql, strlen(sql)) != 0) {
  print_stmt_error(stmt, "Could not prepare statement");
  return;
 }

 // Initialize the result column structures
 memset (param, 0, sizeof (param)); /* zero the structures */
 memset (result, 0, sizeof (result)); /* zero the structures */

 // Init param structure
 // Select
 param[0].buffer_type     = MYSQL_TYPE_LONG;
 param[0].buffer         = (void *) &myId;
 param[0].is_unsigned    = 0;
 param[0].is_null         = 0;
 param[0].length         = 0;

 // Result
 result[0].buffer_type     = MYSQL_TYPE_LONG;
 result[0].buffer         = (void *) &myNumAddresses;
 result[0].is_unsigned    = 0;
 result[0].is_null         = &is_null[0];
 result[0].length         = 0;

 // Bind param structure to statement
 if (mysql_stmt_bind_param(stmt, param) != 0) {
  print_stmt_error(stmt, "Could not bind parameters");
  return;
 }

 // Bind result
 if (mysql_stmt_bind_result(stmt, result) != 0) {
  print_stmt_error(stmt, "Could not bind results");
  return;
 }

 // Set bind parameters
 myId            = id;

 // Execute!!
 if (mysql_stmt_execute(stmt) != 0) {
  print_stmt_error(stmt, "Could not execute statement");
  return;
 }

 if (mysql_stmt_store_result(stmt) != 0) {
  print_stmt_error(stmt, "Could not buffer result set");
  return;
 }

 // Init data
 (*numAddresses) = 0;

 // Fetch
 if(mysql_stmt_fetch (stmt) == 0){
  (*numAddresses) = myNumAddresses;
 }

 // Deallocate result set
 mysql_stmt_free_result(stmt); /* deallocate result set */

 // Close the statement
 mysql_stmt_close(stmt);

 // Close Database
 closeDB(conn);

}

Aquí lo importante a resaltar es que se tiene dos estructuras especiales del API MySQL, param y result, las cuales configuran los parámetros que usará la sentencia preparada así como el sitio donde se guardarán los resultados, respectivamente. En este ejemplo, al hacer la consulta se tendrá el valor en la variable numAddresses.

Referencias


  1. #1 by Luis Gallardo on 18/09/2014 - 9:22

    @Maxx you are welcome my friend. Yes it’s a little frustrating not to have the whole example. I hope it helps you. Best regards!

  2. #2 by Maxx on 17/09/2014 - 6:01

    Thanks a lot for this. I was also following the book just for using prepared statements using SELECT which the books doesn’t shows in details. The book only shows how to bind result with prepared select not how to bind parameter and to call mysql_bind_param and mysql_bind_results successively.

    This article showed me just what i need. Again thanks a lot.

  3. #3 by Luis Gallardo on 10/05/2012 - 3:54

    @gruena my_bool is the type. It’s defined by the API itself. Cheers!

  4. #4 by gruena on 10/05/2012 - 1:55

    Hello, thanks for the article! :)

    Just one question: what shall the type my_bool be?

Los Comentarios están cerrados