И это не единственный способ сделать это
Структуру MYSQL_FIELD можно получить также с помощью функции mysql_ fetch_fields().
До сих пор во всех примерах этого раздела, речь шла о запросах, возвращающих ре­зультирующий набор. А как же быть с такими SQL-командами, как INSERT и UPDATE, не возвращающими никаких данных вообще?
В случае использования запросов, которые не возвращают результирующего набора, но осуществляющих изменения в записях базы данных (INSERT, UPDATE, DELETE и т.д.), количество строк, задействованных в запросе, можно получить с помощью функции mysql_affected_rows(). Ниже представлен пример обработки запроса такого типа.
Листинг 19.20.
#include <stdio.h> #include <mysql.h> int main()
{
/* объявить структуры данных и переменные */ MYSQL mysql; MYSQL_RES *result;
/* инициализировать структуру MYSQL */
mysql_init(&mysql);
/* подключиться к базе данных */
if (!(mysql_real_connect(&mysql, "localhost", "user", "pass",
"web", 0, NULL, 0)))
{
fprintf(stderr, " Ошибка соединения: %sn", mysql_error(&mysql)); exit();
}
/* выполнить запрос UPDATE */
/* и вернуть количество измененных строк */
if (mysql_query, (&mysql "UPDATE data SET vcount = vcount+1") !=
0)
{
fprintf(stderr, " Ошибка в запросе: %sn", mysql_error(&mysql); exit();

 } 

else
{
fprintf(stdout, "Запрос выполнен успешно, обработано %d строк
n",
mysql_affected_rows (&mysql));
}
/* очистка */
mysql_free_result(result); mysql_close(&mysql);
}
С помощью функции mysql_field_count() легко определить, должен ли запрос возвращать результирующий набор. Эта функция возвращает количество полей, ожидаемых в результирующем наборе. Если эта функция возвращает 0, это означает, что никаких полей не возвращается. Обычно это случается при выполнении запросов типа, отличного от SELECT (в дальнейшем будем называть их "не SELECT"). Таким образом, функция mysql_field_count() может пригодиться при определении типа последнего выполненного запроса и написании универсального клиента MySQL.
Следующий пример демонстрирует использование функции mysql_field_count() для определения типа выполняемого запроса ("SELECT" или "не SELECT"), после чего принимается решение о том, каким образом запрос будет обрабатываться в дальнейшем.
Листинг 19.21.
#include <stdio.h> #include <mysql.h> int main()
{
/* объявить структуры данных и переменные */ MYSQL mysql; MYSQL_RES *result;
/* инициализировать структуру MYSQL */
mysql_init(&mysql);
/* подключиться к базе данных */
if (!(mysql_real_connect(&mysql, "localhost", "john", "doe",
"test", 0, NULL, 0)))
{
fprintf(stderr, "Ошибка соединения: %sn", mysql_error(&mysql)); exit();
}
/* выполнить запрос */
/* при ошибке - вывести сообщение об ошибке */
/* если нет - проверить тип запроса и обработать его соответствую­щим образом */
if (mysql_query, (&mysql "INSERT INTO logs VALUES (99, NOW(), 'Apache server shutdown') ") != 0)
{
fprintf(stderr, " Ошибка в запросе: %sn", mysql_error(&mysql); exit();
}
else
{
if (result = mysql_store_result(&mysql))
{
/* получен результат? Тогда это должен быть оператор
SELECT... */ 
/* обработать результирующий набор */
fprintf(stdout, "Результирующий набор содержит какие-то поля, значит это должен быть запрос SELECT queryn");
/* освободить результирующий набор */ mysql_free_result(result);
}
else
{
/* нет результата? Это должен быть запрос не SELECT */ /* или ошибочный запрос SELECT */ if (mysql_field_count(&mysql) == 0)
{
/* запрос не SELECT */
fprintf(stdout, " Результирующий набор не содержит по­лей, должно быть это
не SELECT запрос n");
}
else
{
/* ошибка */
fprintf(stderr, " Ошибка чтения результирующего набора:
%sn",
mysql_error(&mysql)); exit();
}
}
}
/* очистка */ mysql_close(&mysql);
}
Для того чтобы освободить память, занятую результирующим набором, всегда можно воспользоваться функцией mysql_free_result(). Если этого не сделать, результирующий набор будет продолжать занимать место в памяти даже после завершения соединения с базой данных, из которой этот результирующий набор был получен.
Листинг 19.22.
/* освободить память, занятую результирующим набором */ mysql_free_result(&mysql);
Дополнительные функции, имеющие отношение к обработке результирующих наборов, перечислены в табл. 19.1.
Обработка результирующего набора