Procesar un conjunto de resultados

Hay un conjunto de funciones que se aplican a un conjunto de resultados para obtener información sobre él.

Número de elementos de un conjunto de resultados

Una de las primeras cosas que puede interesarnos es saber cuantos elementos contiene el conjunto de resultados. Para obtener ese valor se puede usar la función mysql_num_rows.

Número de columnas por fila de un conjunto de resultados

Otro parámetro interesante es el número de columnas por fila, para obtenerlo se puede usar la función mysql_num_fields.

Ambas funciones requieren como parámetro un puntero a una estructura MYSQL_RES, y ambas retornan un entero.

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

Información sobre columnas

También podemos obtener información sobre cada una de las columnas del conjunto de resultados. Para ello disponemos de las funciones mysql_fetch_field, mysql_fetch_fields y mysql_fetch_field_direct.

La primera obtiene información sobre una de las columnas, en una estructura MYSQL_FIELD. La primera vez que se use devuelve la información sobre la primera columna, la segunda vez sobre la siguiente, etc.

   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;
   }

La función mysql_fetch_fields devuelve la información sobre todas las columnas a la vez, en un array de estructuras.

MYSQL_FIELD.

   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;
   }

La tercera función, mysql_fetch_field_direct, devuelve la información sobre la columna indicada por el número especificado como segundo parámetro:

   // Información sobre columnas n:
   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;

Contenido de las filas de un conjunto de resultados

Por supuesto, también nos interesa obtener cada una de las filas contenidas en el conjunto de resultados. Para esa tarea se usa se la función mysql_fetch_row. Esta función también requiere como parámetro una estructura MYSQL_RES, y da como salida una estructura MYSQL_ROW.

   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;
   }

También podemos usar como condición el valor de retorno de la función mysql_fetch_row, ya que tal valor es NULL si no quedan filas por recuperar.

El tipo MYSQL_ROW no es más que un array de cadenas, (un char**), que contiene los valores de todas las columnas en la forma de un array de cadenas. Si alguno de los valores de un atributo es NULL, el puntero correspondiente a esa columna será NULL.

Obtener longitudes de columnas

Mediante la función mysql_fetch_lengths podemos obtener las longitudes de todas las columnas de la fila actual de un conjunto de resultados.

Estos valores se pueden usar para copiar esos valores sin necesidad de calcular sus longitudes, o cuando algunas de las columnas contengan valores binarios, en cuyo caso no podremos usar strlen para calcular esas longitudes.

   // 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;
      }
   }

Acceder a filas del conjunto de forma aleatoria

Mediante mysql_fetch_row accedemos a las filas del conjunto de resultados de forma secuencial. Sin embargo, todas las filas del conjunto de resultados están en memoria, de modo que podemos acceder a ellas en cualquier orden, o acceder sólo a algunas de ellas.

Para acceder a una fila arbitraria se usa la función mysql_data_seek. Esta función precisa dos parámetros. El primero es el conjunto de resultados y el segundo un desplazamiento entre 0 y mysql_num_rows(result)-1.

   // 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;
   }

También podemos usar la función mysql_row_tell para obtener el valor de desplazamiento de la fila actual.

Ese valor se puede usar como argumento en llamadas a la función mysql_row_seek, pero el valor usado por estas dos funciones no es un número de fila, por lo tanto, no se puede usar en la función mysql_data_seek.

   MYSQL_ROW_OFFSET pos;
   pos = mysql_row_tell(res);
   // lecturas de filas
   mysql_row_seek(res, pos);
   row = mysql_fetch_row(res);
   cout << "Fila guardada" << endl;
   for(k = 0 ; k < j ; k++) \{
      cout << ((row[k]==NULL) ? "NULL" : row[k]) << endl;
   }

Comentarios de los usuarios (1)

Ulises
2017-11-27 05:39:08

No puedo asociar a la funcion "mysql_store_result()" con el puentero que dirigiria la info de la base de datos a la estructura MYSQL_RES. Pues me dice que "res" no esta declarado, intente de todo y no lo puedo hacer andar. Si alguien me ayuda le agradezeria un monton !! saludos.