Так как функция mysql_fetch_row() обрабатывает одну строку за один прием, для просмотра всего результирующего набора, возвращенного запросом, она обычно используется в цикле.
Листинг 19.17.
#include <stdio.h> #include <mysql.h> int main()
{
/* объявить структуры данных и переменные */ MYSQL mysql; MYSQL_RES *result; MYSQL_ROW row;
int count;
/* инициализировать структуру MYSQL */
mysql_init(&mysql);
/* подключиться к базе данных */
if (!(mysql_real_connect(&mysql, "localhost", "john", "doe", "db1",
0, NULL, 0)))
{
fprintf(stderr, " Ошибка соединения: %sn", mysql_error(&mysql)); exit();
}
/* выполнить запрос */
if (mysql_query, (&mysql "SELECT title, author FROM books") != 0)
{
fprintf(stderr, " Ошибка в запросе: %sn", mysql_error(&mysql); exit();
}
/* проверка правильности результирующего набора */ if (!(result = mysql_store_result(&mysql)))
{
fprintf (stderr, " Ошибка чтения результирующего набора: %sn", mysql_error (&mysql) ); exit(2);
}
else
{
/* если набор правильный - */
/* просмотр строки и распечатка содержимого */ int numRecords = mysql_num_rows(result); for (count = 0; count < numRecords; count++)
{
row = mysql_fetch_row(result); fprintf(stdout, "%s - %sn", row[0], row[1]);
}
mysql_free_result(result);
}
/* очистка */ mysql_close(&mysql);

 } 
В предыдущем примере из запроса понятно, что результирующий набор содержит только два поля, поэтому в исходном коде жестко прописан доступ только к первым двум элементам массива, в которых хранится строка. Однако такой подход не даст результата, если предварительно неизвестно, сколько полей содержится в результирующем наборе. Эта ситуация встречается очень часто, особенно при использовании запроса типа SELECT *.
В таком случае обычно не пользуются жестким программированием количества полей в результирующем наборе, для их динамического определения рекомендуется применять функцию mysql_num_fields(), что значительно удобнее. Затем при распечатке со­держимого полей из строки, число, возвращенное функцией mysql_num_fields() , служит основой для создания цикла, вложенного внутрь главного цикла.
Следующая версия предыдущего примера иллюстрирует этот более тонкий подход.
Листинг 19.18.
#include <stdio.h> #include <mysql.h> int main() {
/* объявить структуры данных и переменные */ MYSQL mysql; MYSQL_RES *result; MYSQL_ROW row;
int count;
/* инициализировать структуру MYSQL */
mysql_init(&mysql);
/* подключиться к базе данных */
if (!(mysql_real_connect(&mysql, "localhost", "john", "doe", "db1", 0, NULL, 0)))
{
fprintf(stderr, " Ошибка соединения: %sn", mysql_error(&mysql)); exit();
}
/* выполнить запрос */
if (mysql_query, (&mysql "SELECT * FROM accounts") != 0)
{
fprintf(stderr, " Ошибка в запросе: %sn", mysql_error(&mysql); exit();
}
/* проверка правильности результирующего набора */ if (!(result = mysql_store_result(&mysql)))
{
fprintf (stderr, " Ошибка чтения результирующего набора: %sn", mysql_error (&mysql) ); exit(2);
}
else
{
/* если набор правильный */
/* просмотр строк и распечатка содержимого */
/* для каждой строки просмотр полей и распечатка содержимого
*/
int numRecords = mysql_num_rows(result); int numFields = mysql_num_fields(result); for (i = 0; i < numRecords; i++) 
{
row = mysql_fetch_row(result);
for (j = 0; j < numFields; j++) fprintf(stdout, "%s",
row[j]);
{
(j != (numFields-1) ? printf(", ") :
printf("n");
}
}
mysql_free_result(result);
}
/* очистка */ mysql_close(&mysql);
}
Кроме того, есть возможность получить детализированную информацию по атрибутам каждого поля записи. Для этих целей служит функция mysql_fetch_field() . Функция mysql_fetch_field() возвращает структуру MYSQL_FIELD, элементы которой содержат информацию о соответствующем поле - его имя, длину, тип данных, значение по умолчанию, максимальную длину, ключи и допустимые значения. Рассмотрим следующий пример (см. также руководство по MySQL, содержащее детальную информацию об элементах структуры MYSQL_FIELD).
Листинг 19.19.
#include <stdio.h> #include <mysql.h> int main()
{
/* объявить структуры данных и переменные */ MYSQL mysql; MYSQL_RES *result; MYSQL_FIELD *field;
/* инициализировать структуру MYSQL */
mysql_init(&mysql);
/* подключиться к базе данных */
if (!(mysql_real_connect(&mysql, "accounts.localdomain.com",
"john", "doe", "db1", 0, NULL, 0)))
{
fprintf(stderr, " Ошибка соединения: %sn", mysql_error(&mysql)); exit();
}
/* выполнить запрос */
/* в случае ошибки - отобразить сообщение об ошибке */
/* иначе - проверить тип запроса и */
/* соответствующим образом обработать его */
if (mysql_query, (&mysql "SELECT * FROM accounts") != 0)
{
fprintf(stderr, " Ошибка в запросе: %sn", mysql_error(&mysql); exit();
}
else
result = mysql_store_result(&mysql); /* итерация по полям записи */ while((field = mysql_fetch_field(result)))
{
printf(" имя: %s, ", field->name); /* имя поля */ 
printf(" размер: %d, ", field->length); /* размер поля */
printf(" тип: %d, ", field->type); /* тип поля */
printf (" макс. длина: %d, ", field->max_length); /* макс.
длина поля в этом результирующем наборе */
printf (" разрешение значений NULL: %s, ",
IS_NOT_NULL(field->flags) ? "нет" : "да"); /* разрешение значений NULL
*/
printf (" первичный ключ: %sn", IS_PRI_KEY(field->flags) ? " да" : " нет"); /* является ли поле первичным ключом */
}
mysql_free_result(result);
}
/* очистка */ mysql_close(&mysql);
}