Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

Интерфейс для С (C API)


Коротко о главном

API поддерживает богатый ассортимент функций, которые обеспечивают доступ к СУБД MySQL из программы пользователя, независимо от того, запущена ли она в локальной или на удаленной системе.

Подготовка

Вы должны подключить файл mysql.h в начале Вашей программы на C:

    #include "mysql.h"

Вы также должны компоновать программу с математической (для шифрования) и mysqlclient библиотеками:

    $ cc -I/usr/include/mysql -L/usr/lib/mysql myapp.c -o myapp -lm -lmysqlclient

Включаемые файлы обычно размещены в /usr/include/mysql, а библиотеки могут быть найдены в /usr/lib/mysql.

Если Вы имеете утечку памяти в вашей программе-клиенте, Вы можете компилировать с опцией --with-debug=yes. Это заставит код клиента использовать пакет 'safe_malloc' в библиотеке клиентов MySQL. Вызовите TERMINATE(stdout) или my_end(1) в вашей прикладной программе-клиенте перед выходом, чтобы получить список всех утечек памяти. Детали - в файле mysys/safemalloc.c из дистрибутива MySQL.

Рассмотрим простой пример MySQL-клиента, который только выполнит SELECT и выведет все возвращенные строки в STDOUT. В нем использованы далеко не все функции С API, он должен только дать Вам представление о типичном виде программы-клиента.


#include <stdio.h>
#include <stdlib.h>
#include "mysql.h"

MYSQL mysql;
MYSQL_RES *res;
MYSQL_ROW row;

void exiterr(int exitcode)
{
  fprintf(stderr, "%s\n", mysql_error(&mysql));
  exit(exitcode);
}

int main()
{
  uint i = 0;

  if (!(mysql_connect(&mysql,"host","username","password")))
     exiterr(1);
  if (mysql_select_db(&mysql,"payroll")) exiterr(2);
  if (mysql_query(&mysql,"SELECT name,rate FROM emp_master"))
     exiterr(3);
  if (!(res = mysql_store_result(&mysql))) exiterr(4);
  while((row = mysql_fetch_row(res))) {
    for (i=0 ; i < mysql_num_fields(res); i++)
      printf("%s\n",row[i]);
  }
  if (!mysql_eof(res)) exiterr(5);
  mysql_free_result(res);
  mysql_close(&mysql);
}

Клиентские функции

MySQL API использует структуры данных MYSQL (определены в mysql.h) чтобы установить связь с СУБД. Вы можете устанавливать много соединений из одной программы-клиента, однако, каждое соединений должно быть связано с собственной отдельной структурой MYSQL.

После успешного запроса, если данные должны быть возвращены пользователю, набор результатов должен быть передан через функции mysql_use_result или через функцию mysql_store_result. Обе эти функции сохраняют набор результатов в структуре MYSQL_RES. Разница в том, что mysql_store_result передает весь набор результатов в память клиента, а mysql_use_result инструктирует клиента, чтобы он мог получить строку динамически с сервера с каждым обращением к mysql_fetch_row. Имейте в виду, что mysql_use_result занимает ресурсы сервера, и не должен использоваться для интерактивных прикладных программ, где действия пользователя часто непредсказуемы и могут привести к большим задержкам. Обратите внимание также, что Вы можете держать только одно соединение, которое использует mysql_user_result, открытым, и это должно быть последнее созданное соединение. По умолчанию процесс mysqld закроет соединение после тридцати секунд неактивности.

Данные, переданные из набора результатов с помощью mysql_fetch_row, будут помещены в структуру MYSQL_ROW, которая является просто массивом указателей на начало каждого поля.


mysql_affected_rows

СИНТАКСИС:

    int mysql_affected_rows(MYSQL *mysql)

ОПИСАНИЕ:

    Возвращает число строк, на которые воздействует последний UPDATE, DELETE или INSERT.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ:

  • Целое число > 0 показывает число измененных строк.
  • Ноль, если никакие записи не соответствовали предложению WHERE в UPDATE или DELETE.
  • -1, если запрос возвратил ошибку, например, была сделана попытка добавить двойной первичный ключ в течение одного INSERT.

ПРИМЕР:

mysql_query(&mysql,"INSERT INTO gl_transact(acctnbr, amount) VALUES(12345,
            651.30)");
if (mysql_affected_rows(&mysql) < 0)
   fprintf(stderr, "Attempted to add duplicate primary key\n");

MySQL оптимизирован для случая удаления всех записей в таблице. Побочный эффект этой оптимизации - то, что MySQL возвратится, ноль для числа строк, на которые воздействовал в этой ситуации. Выполнение 'select count(*) from the_table' перед удалением всех записей даст Вам значение = на сколько строк воздействовала система, хотя это значение может изменяться между SELECT и DELETE. MySQL 3.20.X не поддерживает блокировку таблицы. Это исправлено в версии 3.21.X


mysql_close

СИНТАКСИС:

    void mysql_close(MYSQL *mysql);

ОПИСАНИЕ:

    Закрывает открытое соединение подключение. mysql_close должен быть вызван после завершения всех операций, выполняемых через соединение с MySQL. Если это не сделать, поток, созданный mysql_connect, зависнет до окончания тайм-аута сервера. На сервере, работающем с сильной нагрузкой, это может быстро израсходовать много памяти, хотя нужно очень немного времени центрального процессора.

    Если подключение закрыто до того, как запущенный запрос завершился, запрос будет продолжаться, пока не попытается вернуть результат пользователю. При этом он завершится аварийно, узнав, что соединение не активно.

    По умолчанию тайм-аут = 30 секундам для активного запроса и 8 часам для открытого подключения.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ:

    Нет.

mysql_connect

СИНТАКСИС:

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

ОПИСАНИЕ:

Пытается установить соединение с сервером MySQL, работающем на компьютере host. Значение host может быть сетевым именем или IP адресом. Параметр user задает логин пользователя MySQL, параметр passwd задает пароль для user. ОБРАТИТЕ ВНИМАНИЕ: Не пытайтесь шифровать passwd перед вызовом mysql_connect. Шифрование выполняется автоматически клиентским API.

  • Если host не задан, то подразумевается 'localhost'.
  • Если user не задан, то подразумевается 'current user'. Под Windows ODBC, текущий пользователь должен быть определен явно. Под Unix подразумевается текущий логин.
  • Если password не задан, то будут проверены только те записи в таблице пользователей, которые не имеют пароля. Это позволяет db-администратору настроить систему привилегий MySQL так, чтобы пользователь получал различные привилегии в зависимости от того, определен пароль или нет. Иногда полезно.

mysql_connect должен успешно завершиться до каких-либо действий с базой данных.

Вы можете опционально задать первый аргумент mysql_connect как (MYSQL*) 0. Это вынудит C API к автоматическому распределению памяти для структуры подключения и освобождению ее при завершении. Расплатой за это служит то, что Вы не сможете получать сообщения об ошибках из mysql_connect, когда используете эту опцию.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ:

  • mysql, если соединение выполнено успешно.
  • NULL в случае, если связаться не удалось.

ПРИМЕР:


MYSQL *mysql;

if ((mysql = malloc(sizeof(MYSQL))) != NULL)
{
   if (!(mysql_connect(mysql, "pr_server", "jqpublic", "mypasswd")))
   {
      free(mysql);
      exit(1);
   }
}
free(mysql);

mysql_create_db

СИНТАКСИС:

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

ОПИСАНИЕ:

    Создает базу данных, именованную как db на машине, указанной в mysql. MySQL подключение должно быть выполнено с правами пользователя, который имеет право создавать базы данных. Обратитесь к главе "Администрирование пакета" за подробностями о правах доступа.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ:

  • 0, если база данных создана успешно.
  • Не 0, если произошла ошибка. Сообщение об ошибке можно получить с помощью функции mysql_error.

mysql_data_seek

СИНТАКСИС:

    void mysql_data_seek(MYSQL_RES *res, uint offset);

ОПИСАНИЕ:

    Переходит на указанную строку в наборе результатов запросов. Не может использоваться вместе с mysql_use_result.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ:

    Нет.

mysql_drop_db

СИНТАКСИС:

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

ОПИСАНИЕ:

    Удаляет базу данных с именем, указанным в db на сервере, указанном в mysql. Подключение должно быть выполнено с правами пользователя, который имеет на это право. Обратитесь к главе "Администрирование пакета" за подробностями о правах доступа.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ:

  • 0, если база данных удалена успешно.
  • Не 0, если произошла ошибка. Сообщение об ошибке можно получить с помощью функции mysql_error.

mysql_eof

СИНТАКСИС:

    int mysql_eof(MYSQL_RES *)

ОПИСАНИЕ:

Возвращает значение != 0, если последний вызов mysql_fetch_row не вернул ничего потому, что достигнут конец набора результатов.


mysql_error

СИНТАКСИС:

    char *mysql_error(MYSQL *mysql)

ОПИСАНИЕ:

    Выводит сообщение об ошибке, если ошибку вернула последняя вызванная функция MySQL. В противном случае возвращает пустую строку.

mysql_fetch_field

СИНТАКСИС:

    MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *handle);

ОПИСАНИЕ:

    Находит тип поля таблицы.


mysql_fetch_lengths

СИНТАКСИС:

    unsigned int *mysql_fetch_lengths(MYSQL_RES *mysql)

ОПИСАНИЕ:

    Возвращает длину всех столбцов в наборе результатов запросов. Если Вы планируете получение данных, содержащих \0, Вы должны использовать эту функцию, чтобы получить фактическую длину значения поля.


mysql_fetch_row

СИНТАКСИС:

    MYSQL_ROW mysql_fetch_row(MYSQL_RES *mysql);

ОПИСАНИЕ:

    Выбирает следующую строку в результате запроса. Возвратит пустой указатель, когда все строки были получены.


mysql_field_seek

СИНТАКСИС:

    void mysql_field_seek(MYSQL_RES *result, int field)

ОПИСАНИЕ:

    Помещает курсор столбца в поле номер field, который должен быть в диапазоне от 0 до mysql_num_fields(MYSQL_RES*)-1.

mysql_free_result

СИНТАКСИС:

    void mysql_free_result(MYSQL_RES *result);

ОПИСАНИЕ:

    Освобождает память, использованную, чтобы сохранить результат запроса. Должна быть вызвана всякий раз, когда Вы закончили использовать результаты вызова mysql_store_result().


mysql_get_client_info

СИНТАКСИС:

    char *mysql_get_client_info(void);

ОПИСАНИЕ:

Эта функция просто возвращает строку с информацией о версии используемой в настоящее время клиентской библиотеки. Иногда полезно.


mysql_get_host_info

СИНТАКСИС:

    char *mysql_get_host_info(MYSQL *mysql);

ОПИСАНИЕ:

    Возвращает имя сервера (заданное в аргументе "host" при вызове mysql_connect).


mysql_get_proto_info

СИНТАКСИС:

    int mysql_get_proto_info(MYSQL *mysql);

ОПИСАНИЕ:

    Получает версию протокола, используемую подключением. MySQL поддерживает динамические протоколы, основанные на возможностях клиента. В версии 3.20.X это не делает ничего, но в будущих версиях, эта возможность позволит, например, одному пользователю подключать использование текущего протокола, в то время как другой использует шифрование и сжатие.


mysql_get_server_info

СИНТАКСИС:

    char *mysql_get_server_info(MYSQL *mysql);

ОПИСАНИЕ:

Возвращает версию сервера.


mysql_insert_id

СИНТАКСИС:

    int mysql_insert_id(MYSQL *mysql)

ОПИСАНИЕ:

    Возвращает ID, сгенерированный для поля AUTO_INCREMENT переменной результата 'res'.

mysql_list_dbs

СИНТАКСИС:

    MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild);

ОПИСАНИЕ:

    Предоставляет простой способ переноса mSQL прикладных программ. Подобно выполнению 'SHOW databases [ LIKE wild-card ]', как запроса.


mysql_list_fields

СИНТАКСИС:

    MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild);

ОПИСАНИЕ:

    Предоставляет простой способ переноса mSQL прикладных программ. Подобно выполнению 'SHOW fields [FROM table] [FROM database] [LIKE wild-card]', как запроса.


mysql_list_processes

СИНТАКСИС:

    MYSQL_RES *mysql_list_processes(MYSQL *mysql);

ОПИСАНИЕ:

    Получает список потоков, в настоящее время запущенных на сервере MySQL. Вы должны иметь привилегии process.


mysql_list_tables

СИНТАКСИС:

    MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild);

ОПИСАНИЕ:

    Предоставляет простой способ переноса mSQL прикладных программ.

    Вызывает как запрос 'SHOW tables [FROM database]'.



mysql_num_fields

СИНТАКСИС:

    int mysql_num_fields(MYSQL_RES *result);

ОПИСАНИЕ:

    Возвращает количество столбцов (полей) в результате запроса.

ПРИМЕР:


MYSQL mysql;
MYSQL_RES *result;
int fields;

if (mysql_query(&mysql, "SELECT * FROM emp_master") == 0)
{
   result = mysql_store_result( &mysql );
   if (result != NULL )
   {
      fields = mysql_num_fields( result );
      printf( "Retrieved %u fields\n", fields );
   }
   else printf( "Query failed\n" );
}
else abort();

См. также:


mysql_num_rows

СИНТАКСИС:

    int mysql_num_rows(MYSQL_RES *result);

ОПИСАНИЕ:

ПРИМЕР:


MYSQL mysql;
MYSQL_RES *result;
int rows;

if (mysql_query(&mysql, "SELECT * FROM emp_master") == 0)
{
   result = mysql_store_result(&mysql );
   if (result != NULL)
   {
      rows = mysql_num_rows(result);
      printf("Retrieved %u rows\n", rows);
   }
   else printf("Query failed\n");
}
else abort();

См. также:


mysql_query

СИНТАКСИС:

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

ОПИСАНИЕ:

    Выполняет SQL запрос указанный query к базе данных, указанной в mysql. Эта функция возвращает 0, если запрос выполнен успешно. Результат, отличный от нуля, указывает на ошибку. Обращение к mysql_error выведет текстовое сообщение об ошибке.

    Вызов mysql_num_rows даст Вам число строк, возвращенных запросом.

    Если Вы имеете поле AUTO_INCREMENT в модифицируемой таблице, и выполняете оператор INSERT, Вы можете получить последнее назначенное значение поля, проверяя mysql_insert_id.


mysql_real_query

СИНТАКСИС:

    int mysql_real_query(MYSQL *mysql, const char *query, uint length);

ОПИСАНИЕ:

    Эта функция вызывается mysql_query после того, как она выполнила обращение к функции strlen чтобы вычислить длину строки запроса. Это можно использовать, если Ваша программа распределяет фиксированный буфер для строки запроса.

    Вы будете должны использовать эту функцию, если Вы имеете данные, в которые значение \0 входит не как последнее.


mysql_reload

СИНТАКСИС:

    int mysql_reload(MYSQL *mysql);

ОПИСАНИЕ:

    Перезагружают таблицу доступа пользователей, очищает все кэши и закрывает все открытые неиспользуемые таблицы. Должна быть вызвана перед запуском isamchk на любой таблице. Требует, чтобы пользователь имел право на перезагрузку (reload).


mysql_select_db

СИНТАКСИС:

    int mysql_select_db(MYSQL *mysql, const char *db);

ОПИСАНИЕ:

    Пытается соединиться с базой данных, указанной в db, на сервере, указанном в mysql. Сервер СУБД MySQL использует логин и пароль, содержащиеся в mysql, чтобы опознать подключение. Перед использованием mysql_select_db необходимо успешно вызвать mysql_connect.

    mysql_select_db должен быть вызван успешно перед попыткой сделать запрос к базе данных. Исключительные ситуации - запросы типа:

    SHOW DATABASES like 'A%';

    SELECT 1+1; # SELECT без использования таблиц(ы).


mysql_shutdown

СИНТАКСИС:

    int mysql_shutdown(MYSQL *mysql);

ОПИСАНИЕ:

    Останавливает сервер СУБД MySQL. Пользователь должен иметь право shutdown.


mysql_stat

СИНТАКСИС:

    char *mysql_stat(MYSQL *mysql);

ОПИСАНИЕ:

    Возвращает информацию, которую выдает команда 'mysqladmin version' в виде строки символов. Эквивалентно опции stat программы mysqladmin. В строку включается информация о простое в секундах, запущенных потоках, запросах, перезагрузках и открытых таблицах.


mysql_store_result

СИНТАКСИС:

    MYSQL_RES *mysql_store_result(MYSQL *mysql);

ОПИСАНИЕ:

    Передает результат клиенту. Вы должны использовать эту функцию или mysql_use_result() чтобы получить результат с сервера. Вы обязательно должны использовать mysql_store_result() или mysql_use_result() после того, как выполнили успешный запрос.

    mysql_store_result() вернет NULL при ошибке или если инструкция не вернула никаких данных. Вы можете обрабатывать ошибки так:

    if (!(result=mysql_store_result(&mysql)) &&
            mysql_num_fields(&mysql))
            fputs(mysql_error(&mysql),stderr);
    

    Вызов mysql_free_result() должен быть выполнен, чтобы освободить память.


mysql_use_result

СИНТАКСИС:

    MYSQL_RES *mysql_use_result(MYSQL *mysql);

ОПИСАНИЕ:

    То же, что и mysql_store_result(), за исключением того, что результат выдается сервером динамически для каждого вызова mysql_fetch_row(). Эта функция не должна использоваться в интерактивных прикладных программах, так как она связывает сервер. Зато она помогает уменьшить использование памяти на стороне клиента.

В заключение хочется попросить Вас, если Вам понравилась эта страничка или пригодилась изложенная здесь информация, послать благодарность автору. Это поможет мне вести статистику того, скольким людям пригодилось хоть что-то из моих трудов.

Локальное оглавление.

На главную страничку.