Глава 25. Коннекторы и API

Коннекторы MySQL обеспечивают связь сервера MySQL и программ-клиентов. API обеспечивает низкоуровневый доступ к протоколу и ресурсам MySQL. То и другое позволяет работать с MySQL из почти любого языка или окружения.

Номера версий коннекторов не коррелируют с номерами версий MySQL.

Коннекторы MySQL

Oracle развивает много коннекторов:

MySQL C API

Для прямого доступа к MySQL в приложениях на C есть два метода:

Чтобы получить доступ к MySQL из приложения C или создать интерфейс к MySQL для языка, не поддержанного коннекторами или API в этой главе, стоит начать с C API . Есть много инструментов: которые могут помочь, см. главу 5.7.

MySQL API третьей стороны

Оставшиеся API, описанные в этой главе, предоставляет интерфейс MySQL с определенных языков. Эти решения не развиваются и не поддерживаются Oracle. Основная информация об их использовании и способностях обеспечена здесь только в справочных целях.

Все они реализованы через libmysqlclient или нативный драйвер. Эти два решения предлагают различные плюсы:

Таблица 25.1 перечисляет многие из библиотек и интерфейсов, доступных для MySQL. Таблица 25.2 показывает соответствие версий коннекторов и сервера.

Таблица 25.1. MySQL API и интерфейсы

Окружение APIТип Замечания
AdaGNU Ada MySQL Bindings libmysqlclient См. MySQL Bindings for GNU Ada
CC APIlibmysqlclient См. раздел 25.8. MySQL C API.
CConnector/CЗамена для libmysqlclientСм. MySQL Connector/C Developer Guide.
C++Connector/C++libmysqlclient См. MySQL Connector/C++ Developer Guide.
MySQL++libmysqlclient См. веб-сайт MySQL++ .
MySQL wrappedlibmysqlclient См. MySQL wrapped.
CocoaMySQL-Cocoalibmysqlclient Слвместим с окружением Objective-C Cocoa. См. http://mysql-cocoa.sourceforge.net/
DMySQL for D libmysqlclientСм. MySQL for D.
EiffelEiffel MySQLlibmysqlclient См. раздел 25.14. MySQL Eiffel Wrapper.
Erlangerlang-mysql-driver libmysqlclientСм. erlang-mysql-driver.
HaskellHaskell MySQL BindingsНативный драйвер Brian O'Sullivan's pure Haskell MySQL bindings.
hsql-mysql libmysqlclient Драйвер MySQL для Haskell.
Java/JDBCConnector/JНативный драйвер См. MySQL Connector/J 5.1 Developer Guide.
KayaMyDBlibmysqlclient См. MyDB.
LuaLuaSQLlibmysqlclient См. LuaSQL .
.NET/MonoConnector/NetНативный драйвер См. MySQL Connector/Net Developer Guide.
Objective CamlOBjective Caml MySQL Bindings libmysqlclient MySQL Bindings for Objective Caml.
OctaveDatabase bindings for GNU Octave libmysqlclient Database bindings for GNU Octave.
ODBCConnector/ODBClibmysqlclient См. MySQL Connector/ODBC Developer Guide.
PerlDBI/DBD::mysql libmysqlclient См. раздел 25.10. MySQL Perl API .
Net::MySQLНативный драйвер Net::MySQL at CPAN
PHPmysql и устаревший ext/mysqllibmysqlclient См. Original MySQL API.
mysqli, ext/mysqli interfacelibmysqlclientСм. MySQL Improved Extension.
PDO_MYSQL libmysqlclientСм. MySQL Functions (PDO_MYSQL).
PDO mysqlndНативный драйвер
PythonConnector/PythonНативный драйвер См. MySQL Connector/Python Developer Guide.
PythonConnector/Python C Extension libmysqlclientСм. MySQL Connector/Python Developer Guide.
MySQLdblibmysqlclient См. раздел 25.11. MySQL Python API.
RubyMySQL/Rubylibmysqlclient libmysqlclient. См. раздел 25.12.1. MySQL/Ruby API.
Ruby/MySQLНативный драйверСм. раздел 25.12.2. Ruby/MySQL API.
SchemeMyscsh libmysqlclient Myscsh.
SPLsql_mysql libmysqlclient sql_mysql for SPL.
TclMySQLtcllibmysqlclient См. раздел 25.13. MySQL Tcl API.

Таблица 25.2. Версии MySQL коннекторов и сервера

Connector Версия коннектора Версия сервера MySQL
Connector/C6.1.0 GA 5.6, 5.5, 5.1, 5.0, 4.1
Connector/C++ 1.0.5 GA5.6, 5.5, 5.1
Connector/J5.1.8 5.6, 5.5, 5.1, 5.0, 4.1
Connector/Net6.5 5.6, 5.5, 5.1, 5.0
Connector/Net6.4 5.6, 5.5, 5.1, 5.0
Connector/Net6.3 5.6, 5.5, 5.1, 5.0
Connector/Net6.2 (Больше не поддерживается) 5.6, 5.5, 5.1, 5.0
Connector/Net6.1 (Больше не поддерживается) 5.6, 5.5, 5.1, 5.0
Connector/Net6.0 (Больше не поддерживается) 5.6, 5.5, 5.1, 5.0
Connector/Net5.2 (Больше не поддерживается) 5.6, 5.5, 5.1, 5.0
Connector/Net1.0 (Больше не поддерживается) 5.0, 4.0
Connector/ODBC5.1 5.6, 5.5, 5.1, 5.0, 4.1.1+
Connector/ODBC3.51 (Unicode не понимает) 5.6, 5.5, 5.1, 5.0, 4.1
Connector/Python2.0 5.7, 5.6, 5.5
Connector/Python1.2 5.7, 5.6, 5.5

25.1. MySQL Connector/ODBC

Руководство по MySQL Connector/ODBC публикуется отдельно, а не как часть руководства по MySQL. Доступны следующие документы:

25.2. MySQL Connector/Net

Руководство по MySQL Connector/Net публикуется отдельно, а не как часть руководства по MySQL. Доступны следующие документы:

25.3. MySQL Connector/J

Руководство по MySQL Connector/J публикуется отдельно, а не как часть руководства по MySQL. Доступны следующие документы:

25.4. MySQL Connector/C++

Руководство по MySQL Connector/C++ публикуется отдельно, а не как часть руководства по MySQL. Доступны следующие документы:

25.5. MySQL Connector/C

Руководство по MySQL Connector/C публикуется отдельно, а не как часть руководства по MySQL. Доступны следующие документы:

25.6. MySQL Connector/Python

Руководство по MySQL Connector/Python публикуется отдельно, а не как часть руководства по MySQL. Доступны следующие документы:

25.7. libmysqld, встраиваемая библиотека сервера MySQL

Встраиваемая библиотека сервера MySQL позволяет выполнить полнофункциональный сервер MySQL в приложении-клиенте. Основная выгода: увеличенная скорость и более простое управление для встраиваемых приложений.

Встроенная библиотека сервера основана на версии клиент-сервер MySQL, которая написана на C/C++. Следовательно, встроенный сервер также написан на C/C++. Нет никакого встроенного сервера, доступного на других языках.

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

Таблица 25.3. Функции встраиваемой библиотеки сервера MySQL

Функция

Когда вызывается

mysql_library_init()

Вызовите это прежде, чем любая другая функция MySQL будет вызвана, предпочтительно пораньше в функции main().

mysql_library_end()

Вызовите перед завершением приложения.

mysql_thread_init()

Вызовите это в каждом потоке, который Вы создаете для доступа к MySQL.

mysql_thread_end()Вызовите это перед вызовом pthread_exit().

Скомпонуйте свой код с libmysqld.a вместо libmysqlclient.a. В целях двоичной совместимости приложения и серверной библиотеки, всегда компилируйте приложение с заголовками от той версии MySQL, которая использовалась для компиляции библиотеки. Например, если libmysqld скомпилирована с заголовками MySQL 5.7, нельзя компилировать приложение с заголовками от MySQL 8.0.

Поскольку функции mysql_library_xxx() также включены в libmysqlclient.a, Вы можете переключаться между версией клиент-сервер и встроенной, только компонуя Ваше приложение с правильной библиотекой. См. раздел 25.8.7.41. mysql_library_init().

Одно различие между встроенным и автономным сервером: у встроенного сервера аутентификация для соединений отключена по умолчанию.

25.7.1. Компиляция программ с libmysqld

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

Чтобы получить библиотеку libmysqld при сборке MySQL из исходных текстов, надо сконфигурировать MySQL с опцией -DWITH_EMBEDDED_SERVER=1. См. раздел 2.8.4. Опции настройки исходных текстов MySQL.

Когда Вы компонуете свою программу с libmysqld, Вы должны также включать определенные для системы библиотеки pthread и некоторые библиотеки, которыми пользуется сервер MySQL. Вы можете получить полный список библиотек, выполняя команду mysql_config --libmysqld-libs.

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

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

gcc mysql_test.c -o mysql_test \
    `/usr/local/mysql/bin/mysql_config --include --libmysqld-libs`

Немедленно после команды gcc следует имя исходного файла программы на C. После этого опция -o задана, чтобы указать, что имя файла, которое следует за ней, является именем, которое компилятор должен дать выходному файлу собранной программы. Следующая строка предписывает компилятору получить местоположение включаемых файлов и библиотек и других настроек для системы, на которой это собрано.

На некоторых не-gcc платформах встроенная библиотека зависит от библиотеки времени выполнения C++. Компоновка может привести к ошибкам недостающего символа (missing-symbol). Чтобы решить это, явно перечислите необходимые библиотеки в командной строке компоновщика или используйте в компоновке компилятор C++.

25.7.2. Ограничения использования встроенного сервера MySQL

У встроенного сервера есть следующие ограничения:

Некоторые из этих ограничений могут быть изменены, редактируя включаемый файл mysql_embed.h и перекомпилируя MySQL.

25.7.3. Опции встроенного сервера

Любые опции, которые могут быть заданы демоном сервера mysqld, могут использоваться со встроенной библиотекой сервера. Параметры сервера могут быть даны в массиве как параметр функции mysql_library_init(), которая инициализирует сервер. Им также можно дать в файле опций (хотя бы my.cnf). Чтобы определить файл опций для программы C, используйте параметр --defaults-file как один из элементов второго параметра функции mysql_library_init() . См. раздел 25.8.7.41. mysql_library_init().

Использование файла опций может облегчить переключение между приложением клиент-сервер и тем, где MySQL встроен. Поместите общие опции под группу [server]. Они будут считаны обеими версиями MySQL. Опции для Client/server-версии должны быть в секции [mysqld]. Опции для встроенной библиотеки сервера MySQL пишутся в разделе [embedded]. Опции, определенные для приложений, идут в разделе [ApplicationName_SERVER].

25.7.4. Примеры встроенного сервера

Эти два примера программы должны работать без изменений в Linux или FreeBSD. Для других операционных систем незначительные изменения необходимы, главным образом, с путями к файлам. Эти примеры разработаны, чтобы дать достаточно информации для Вас, чтобы понять необходимую часть реального приложения. Первый пример является очень простым. Второй пример немного усовершенствован с некоторой проверкой на ошибки. Для первого приведена команда для сборки, для второго показан файл сборки GNUmake.

Пример 1

test1_libmysqld.c

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

MYSQL *mysql;
MYSQL_RES *results;
MYSQL_ROW record;

static char *server_options[] = \
  { "mysql_test", "--defaults-file=my.cnf", NULL };
int num_elements = (sizeof(server_options) / sizeof(char *)) - 1;

static char *server_groups[] = { "libmysqld_server",
  "libmysqld_client", NULL };

int main(void)
{
  mysql_library_init(num_elements, server_options, server_groups);
  mysql = mysql_init(NULL);
  mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "libmysqld_client");
  mysql_options(mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
  mysql_real_connect(mysql, NULL,NULL,NULL, "database1", 0,NULL,0);
  mysql_query(mysql, "SELECT column1, column2 FROM table1");
  results = mysql_store_result(mysql);
  while((record = mysql_fetch_row(results))) {
    printf("%s - %s \n", record[0], record[1]);
  }
  mysql_free_result(results);
  mysql_close(mysql);
  mysql_library_end();
  return 0;
}

Вот командная строка для того, чтобы собрать вышеупомянутую программу:

gcc test1_libmysqld.c -o test1_libmysqld \
    `/usr/local/mysql/bin/mysql_config --include --libmysqld-libs`

Пример 2

Чтобы опробовать пример, создайте каталог test2_libmysqld на том же самом уровне как исходный каталог MySQL. Сохраните test2_libmysqld.c и GNUmakefile в нем и запустите GNU make из каталога test2_libmysqld.

test2_libmysqld.c

/*
 * A simple example client, using the embedded MySQL server library
*/

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

MYSQL *db_connect(const char *dbname);
void db_disconnect(MYSQL *db);
void db_do_query(MYSQL *db, const char *query);

const char *server_groups[] = {
  "test2_libmysqld_SERVER", "embedded", "server", NULL};

int main(int argc, char **argv)
{
  MYSQL *one, *two;

  /* mysql_library_init() must be called before any other mysql
   * functions.
   *
   * You can use mysql_library_init(0, NULL, NULL), and it
   * initializes the server using groups = {
   *   "server", "embedded", NULL
   *  }.
   *
   * In your $HOME/.my.cnf file, you probably want to put:

[test2_libmysqld_SERVER]
language = /path/to/source/of/mysql/sql/share/english
   * You could, of course, modify argc and argv before passing
   * them to this function.  Or you could create new ones in any
   * way you like.  But all of the arguments in argv (except for
   * argv[0], which is the program name) should be valid options
   * for the MySQL server.
   *
   * If you link this client against the normal mysqlclient
   * library, this function is just a stub that does nothing.
   */
  mysql_library_init(argc, argv, (char **)server_groups);
  one = db_connect("test");
  two = db_connect(NULL);
  db_do_query(one, "SHOW TABLE STATUS");
  db_do_query(two, "SHOW DATABASES");
  mysql_close(two);
  mysql_close(one);
  /* This must be called after all other mysql functions */
  mysql_library_end();
  exit(EXIT_SUCCESS);
}

static void die(MYSQL *db, char *fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  vfprintf(stderr, fmt, ap);
  va_end(ap);
  (void)putc('\n', stderr);
  if (db) db_disconnect(db);
  exit(EXIT_FAILURE);
}

MYSQL *db_connect(const char *dbname)
{
  MYSQL *db = mysql_init(NULL);
  if (!db) die(db, "mysql_init failed: no memory");
  /*
   * Notice that the client and server use separate group names.
   * This is critical, because the server does not accept the
   * client's options, and vice versa.
   */
  mysql_options(db, MYSQL_READ_DEFAULT_GROUP, "test2_libmysqld_CLIENT");
  if (!mysql_real_connect(db, NULL, NULL, NULL, dbname, 0, NULL, 0))
     die(db, "mysql_real_connect failed: %s", mysql_error(db));
  return db;
}

void db_disconnect(MYSQL *db)
{
  mysql_close(db);
}

void db_do_query(MYSQL *db, const char *query)
{
  if (mysql_query(db, query) != 0) goto err;
  if (mysql_field_count(db) > 0)
  {
     MYSQL_RES   *res;
     MYSQL_ROW    row, end_row;
     int num_fields;

     if (!(res = mysql_store_result(db))) goto err;
     num_fields = mysql_num_fields(res);
     while ((row = mysql_fetch_row(res))) {
       (void)fputs(">> ", stdout);
       for (end_row = row + num_fields; row < end_row; ++row)
         (void)printf("%s\t", row ? (char*)*row : "NULL");
       (void)fputc('\n', stdout);
     }
     (void)fputc('\n', stdout);
     mysql_free_result(res);
  }
  else (void)printf("Affected rows: %lld\n", mysql_affected_rows(db));
  return;
err:
  die(db, "db_do_query failed: %s [%s]", mysql_error(db), query);
}

GNUmakefile

# This assumes the MySQL software is installed in /usr/local/mysql
inc:= /usr/local/mysql/include/mysql
lib:= /usr/local/mysql/lib

# If you have not installed the MySQL software yet, try this instead
#inc:= $(HOME)/mysql-8.0/include
#lib:= $(HOME)/mysql-8.0/libmysqld

CC := gcc
CPPFLAGS := -I$(inc) -D_THREAD_SAFE -D_REENTRANT
CFLAGS   := -g -W -Wall
LDFLAGS  := -static
# You can change -lmysqld to -lmysqlclient to use the
# client/server library
LDLIBS    = -L$(lib) -lmysqld -lm -ldl -lcrypt

ifneq (,$(shell grep FreeBSD /COPYRIGHT 2>/dev/null))
# FreeBSD
LDFLAGS += -pthread
else
# Assume Linux
LDLIBS += -lpthread
endif

# This works for simple one-file test programs
sources := $(wildcard *.c)
objects := $(patsubst %c,%o,$(sources))
targets := $(basename $(sources))

all: $(targets)

clean:
  rm -f $(targets) $(objects) *.core

25.8. MySQL C API

C API обеспечивает низкоуровневый доступ к MySQL протоколу клиент-сервер и позволяет программам на C получить доступ к содержимому базы данных. Код C API распространяется с MySQL и реализован в библиотеке libmysqlclient.

Большинство других API используют libmysqlclient, чтобы общаться с сервером MySQL. Это означает, что, например, Вы можете использовать в своих интересах многие из тех же самых переменных окружения, которые используются другими программами-клиентами, потому что на них есть ссылки из библиотеки. Для получения списка этих переменных, см. раздел 5.1. Обзор программ MySQL .

Для инструкций по созданию программ-клиентов, используя C API, см. раздел 25.8.4.1. Создание программ-клиентов C API. Для того, чтобы программировать с потоками, см. раздел 25.8.4.3. Написание поточных программ-клиентов C API. Чтобы создать автономное приложение, которое включает клиент и сервер в той же самой программе (и не общается с внешним сервером MySQL), см. раздел 25.7. libmysqld, библиотека встроенного сервера MySQL.

Если после обновления Вы испытываете проблемы с собранными программами-клиентами, например, Commands out of sync или дамп ядра, программы были, вероятно, собраны, используя старый заголовок или файлы библиотеки. В этом случае, проверьте дату файла mysql.h и библиотеки libmysqlclient.a, использованных для компиляции, на предмет их соответствия новой версии MySQL. Если не совпадают, повторно соберите программы с новыми заголовками и библиотеками. Перекомпиляция также может быть необходимой для программ, собранных с совместно используемой библиотекой клиента, если главный номер версии библиотеки изменился (например, libmysqlclient.so.17 сменилась на libmysqlclient.so.18).

У клиентов есть максимальный размер коммуникационного буфера. Размер буфера, который выделен первоначально (16 КБ), автоматически увеличен до максимального размера (16 МБ по умолчанию). Поскольку буферные размеры увеличены только по мере надобности, простое увеличение максимального предела само по себе не заставляет использовать больше ресурсов. Эта проверка размера направлена, главным образом, против ошибочных команд и коммуникационных пакетов.

Коммуникационный буфер должен быть достаточно большим, чтобы вместить единственное выражение SQL (для трафика client-server) и одну строку возвращенных данных (для трафика server-client). Коммуникационный буфер каждого сеанса будет динамически увеличен до максимального предела, чтобы обработать любой запрос или строку. Например, если Вы имеете объект типа BLOB, который содержит до 16 МБ данных, у Вас должен быть предел коммуникационного буфера по крайней мере 16 МБ (и в сервере, и в клиенте). Максимумом значения по умолчанию, встроенным в библиотеку клиента, является 1GB, но максимум значения по умолчанию в сервере составляет 1 МБ. Вы можете увеличить это, изменяя значение параметра max_allowed_packet при запуске сервера. См. раздел 6.1.1. Настройка сервера.

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

25.8.1. Реализация MySQL C API

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

У обеих библиотек есть тот же самый интерфейс. С точки зрения C API, приложение общается с автономным сервером тем же самым путем, что и со встроенным сервером. Клиент может быть создан, чтобы общаться с автономным или встроенным сервером, в зависимости от того, как он скомпонован.

Есть два способа получить заголовок и файлы библиотеки C API, требуемые чтобы создавать программы клиента C API:

В обоих случаях Вы можете установить двоичный дистрибутив, который содержит прекомпилированные файлы C API, или Вы можете использовать дистрибутив исходных текстов, чтобы собрать C API лично.

Обычно Вы устанавливаете что-то одно. Для получения информации о проблемах, связанных с одновременной установкой MySQL Server и Connector/C, см. раздел 25.8.2.

Имена файлов библиотеки, для компоновки клиентов с C API зависят от типа библиотеки и платформы, для которой создан дистрибутив:

Под Unix Вы можете также видеть библиотеки, которые включают в имена _r. До MySQL 5.5 они были созданы как безопасные для потоков (повторно используемые) библиотеки отдельно от не-_r версий. С 5.5, обе библиотеки то же самое, а _r-имена являются ссылками на не-_r-имена. Нет никакой надобности использовать _r-библиотеки. Например, если Вы используете mysql_config , чтобы получить флаги компоновщика, Вы можете использовать mysql_config --libs , во всех случаях, даже для поточных клиентов. Нет никакой потребности использовать mysql_config --libs_r.

25.8.2. Совместная установка MySQL Server и Connector/C

Пакеты MySQL Server и Connector/C обеспечивают файлы для сборки и запуска клиентов MySQL C API. Этот раздел обсуждает, когда возможно установить оба продукта на той же самой системе. Для некоторых форматов упаковки это возможно без конфликта. Для других оба продукта не могут быть установлены в то же самое время.

Это обсуждение принимает использование подобных типов пакета для обоих продуктов (например, пакеты RPM). Это не пытается описать сосуществование пакетов разных типов (например, использование пакетов RPM tar вместе). Также не рассматривается сосуществование пакетов от Oracle и третьих лиц.

Если Вы устанавливаете оба продукта, может быть необходимо скорректировать Ваши средства разработки или среду выполнения, чтобы выбрать один набор заголовочных файлов и библиотек. См. разделы 25.8.4.1. Создание клиентов C API и 25.8.4.4. Запуск клиентов C API.

tar и Zip-файлы устанавливаются в соответствии с каталогом, в который Вы распаковываете их. Например, Вы можете распаковать MySQL Server и Connector/C tar под /usr/local, и они распакуются в различные имена каталогов без конфликта.

Windows MSI использует свой собственный каталог установки, таким образом, MySQL Server и Connector/C не находятся в противоречии.

OS X DMG ставятся в соответствии с тем же самым родительским каталогом, но в различные подкаталоги, таким образом, нет никакого конфликта. Например:

/usr/local/mysql-5.6.11-osx10.7-x86_64/
/usr/local/mysql-connector-c-6.1.0-osx10.7-x86/

Solaris PKG ставятся в соответствии с тем же самым родительским каталогом, но в различные подкаталоги, таким образом, нет никакого конфликта. Например:

/opt/mysql/mysql
/opt/mysql/connector-c

Solaris Connector/C не создает символьных ссылок из системных каталогов таких, как /usr/bin или /usr/lib в каталог установки. Это должно быть сделано вручную при желании после установки.

Для RPM есть несколько типов пакетов RPM. MySQL Server shared и devel RPM-пакеты подобны соответствующим пакетам RPM Connector/C. Эти типы пакетов RPM не могут сосуществовать, потому что RPM-пакеты MySQL Server и Connector/C используют те же самые места установки для связанных с библиотекой файлов. Это означает следующие условия:

RPM-пакеты MySQL Server кроме shared и devel не находятся в противоречии с пакетами Connector/C, и могут быть установлены, если стоит Connector/C. Это включает основной RPM-пакет mysqld.

25.8.3. Пример клиента C API

Многие из клиентов в исходных текстах MySQL написаны на C, такие как mysql, mysqladmin и mysqlshow . Если Вы ищете примеры, которые демонстрируют, как использовать C API, посмотрите на этих клиентов. В пакете исходных текстов пакета они обитают в каталоге client.

25.8.4. Сборка и запуск программ-клиентов C API

Следующие разделы предоставляют информацию о создании программ-клиентов, которые используют C API. Темы включают компиляцию и компоновку клиентов, написание поточных клиентов и поиск неисправностей во время выполнения.

25.8.4.1. Сборка программ-клиентов C API

Компиляция клиентов MySQL под Unix

Примеры здесь используют gcc в качестве компилятора. На некоторых системах могут быть другие компиляторы (например, clang под OS X или FreeBSD, или Sun Studio под Solaris). Скорректируйте примеры по мере необходимости.

Вы, возможно, должны определить опцию -I, когда Вы собираете программу-клиента, которая использует заголовочные файлы MySQL, так, чтобы компилятор мог найти их. Например, если заголовочные файлы установлены в /usr/local/mysql/include, используйте эту опцию:

-I/usr/local/mysql/include

Клиенты MySQL должны быть скомпонованы, используя опцию -lmysqlclient. Вы, возможно, также должны определить опцию -L, чтобы сказать компоновщику, где найти библиотеку. Например, если библиотека установлена в /usr/local/mysql/lib, используйте эти опции в команде:

-L/usr/local/mysql/lib -lmysqlclient

Пути могут быть другими в Вашей системе. Корректируйте опции -I и -L соответственно.

Чтобы сделать более простым процесс сборки, используйте скрипт mysql_config .

mysql_config выводит на экран опции, необходимые для компиляции или компоновки:

shell> mysql_config --cflags
shell> mysql_config --libs

Вы можете выполнить эти команды, чтобы получить надлежащие опции и добавить их вручную к командам компиляции или компоновки. Альтернативно, включайте вывод mysql_config непосредственно в командные строки, используя символы апострофа:

shell> gcc -c `mysql_config --cflags` progname.c
shell> gcc -o progname progname.o `mysql_config --libs`

Под Unix компоновщик пользуется динамическими библиотеками по умолчанию. Чтобы скомпоновать со статической библиотекой клиента вместо этого, добавьте ее путь к команде. Например, если библиотека расположена в /usr/local/mysql/lib:

shell> gcc -o progname progname.o /usr/local/mysql/lib/libmysqlclient.a

Или используйте mysql_config, чтобы обеспечить имя библиотеки:

shell> gcc -o progname progname.o `mysql_config --variable=pkglibdir`/libmysqlclient.a

mysql_config в настоящее время не обеспечивает способа перечислить все библиотеки, необходимые для статической компоновки, таким образом, может быть необходимо назвать дополнительные библиотеки (например, -lnsl -lsocket под Solaris). Чтобы понять, какие библиотеки добавить, используйте mysql_config --libs и ldd libmysqlclient.so (или otool -L libmysqlclient.dylib под OS X).

pkg-config может использоваться в качестве альтернативы mysql_config для того, чтобы получить информацию, такую как флаги компилятора или библиотеки, требуемые, чтобы собрать приложения MySQL. Например, следующие пары команд эквивалентны:

mysql_config --cflags
pkg-config --cflags mysqlclient

mysql_config --libs
pkg-config --libs mysqlclient

Чтобы получить флаги для статической компоновки, используйте эту команду:

pkg-config --static --libs mysqlclient
Компиляция клиентов MySQL под Windows

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

Для сборки клиентов C API под Windows, Вы должны скомпоновать клиентскую библиотеку C, Windows ws2_32 sockets и библиотеку Secur32.

Под Windows Вы можете компоновать свой код с динамической или статической библиотекой клиента C. Статическую библиотеку называют mysqlclient.lib, а динамическую библиотеку libmysql.dll. Кроме того, статическая библиотека импорта libmysql.lib необходима для того, чтобы пользоваться динамической библиотекой.

Если Вы компонуете со статической библиотекой, отказ может произойти, если эти условия не удовлетворены:

Если приложение-клиент создано в режиме отладки и использует статический отладочный C runtime (опция компилятора /MTd), это может компоноваться со статической библиотекой mysqlclient.lib, если эта библиотека была создана, используя ту же самую опцию. Если приложение-клиент использует динамический отладочный C runtime (опция /MD или /MDd в режиме отладки), это должно быть скомпоновано с динамической библиотекой libmysql.dll. Это не может компоноваться со статической библиотекой клиента.

Страница MSDN, описывающая опции: http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx.

Решение проблем компоновки с клиентской библиотекой MySQL

Библиотека клиентов MySQL включает встроенную поддержку SSL. Не нужно определить также -lssl или -lcrypto во время компоновки. Это может фактически привести к проблемам во времени выполнения.

Если компоновщик не может найти библиотеку клиентов MySQL, Вы можете получить ошибки неопределенной ссылки для символов, которые начинаются с mysql_:

/tmp/ccFKsdPa.o: In function `main':
/tmp/ccFKsdPa.o(.text+0xb): undefined reference to `mysql_init'
/tmp/ccFKsdPa.o(.text+0x31): undefined reference to `mysql_real_connect'
/tmp/ccFKsdPa.o(.text+0x69): undefined reference to `mysql_error'
/tmp/ccFKsdPa.o(.text+0x9a): undefined reference to `mysql_close'

Вы должны быть в состоянии решить эту проблему, добавляя -Ldir_path -lmysqlclient в конце Вашей команды компоновки, где dir_path задает путь каталога, где расположена библиотека клиентов. Чтобы определить правильный каталог, попробуйте эту команду:

shell> mysql_config --libs

Вывод mysql_config может указать на другие библиотеки, которые должны быть определены в команде компоновки. Вы можете включать вывод mysql_config непосредственно в Вашу команду:

shell> gcc -o progname progname.o `mysql_config --libs`

Если ошибка происходит во время компоновки, когда символ floor не определен, скомпонуйте с математической библиотекой, добавляя -lm в конец команды. Точно так же, если Вы получаете ошибки неопределенной ссылки для других функций, которые должны существовать в Вашей системе, таких как connect(), проверьте страницу руководства на рассматриваемую функцию, чтобы определить, какие библиотеки Вы должны добавить к команде.

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

mf_format.o(.text+0x201): undefined reference to `__lxstat'

В этом случае Вы должны загрузить последний дистрибутив исходных текстов MySQL или Connector/C и собрать библиотеку клиента MySQL самостоятельно. См. раздел 2.8. Установка MySQL из исходных текстов и MySQL Connector/C Developer Guide.

25.8.4.2. Сборка клиентов C API с применением pkg-config

MySQL включает файл mysqlclient.pc, который предоставляет информацию о конфигурации MySQL для использования командой pkg-config. Это позволяет pkg-config использоваться в качестве альтернативы mysql_config для того, чтобы получить такую информацию, как флаги компилятора или библиотеки, требуемые, чтобы собирать приложения MySQL. Например, следующие пары команд эквивалентны:

mysql_config --cflags
pkg-config --cflags mysqlclient

mysql_config --libs
pkg-config --libs mysqlclient

Последняя команда pkg-config производит флаги для динамической компоновки. Чтобы произвести флаги для статической компоновки, используйте эту команду:

pkg-config --static --libs mysqlclient

На некоторых платформах вывод с и без --static одинаков.

Если pkg-config не находит информацию о MySQL, может быть необходимо установить переменную окружения PKG_CONFIG_PATH к каталогу, где расположен файл mysqlclient.pc, обычно это подкаталог pkgconfig каталога библиотек MySQL. Например (корректируйте местоположение соответственно):

export PKG_CONFIG_PATH=/usr/local/mysql/lib/pkgconfig # sh, bash, ...
setenv PKG_CONFIG_PATH /usr/local/mysql/lib/pkgconfig # csh, tcsh, ...

Местоположением установки mysqlconfig.pc можно управлять, используя опцию INSTALL_PKGCONFIGDIR CMake.

Опция --variable берет имя переменной конфигурации и выводит на экра значениен переменной:

pkg-config --variable=prefix mysqlclient     # installation prefix directory
pkg-config --variable=includedir mysqlclient # header file directory
pkg-config --variable=libdir mysqlclient     # library directory

Чтобы посмотреть значение переменной с помощью pkg-config, используйте параметр --variable:

pkg-config --print-variables mysqlclient

Вы можете использовать pkg-config в пределах командной строки, используя апострофы, чтобы включить вывод, который она производит для особых опций. Например, чтобы откомпилировать и скомпоновать клиентскую программу MySQL, используйте pkg-config так:

gcc -c `pkg-config --cflags mysqlclient` progname.c
gcc -o progname progname.o `pkg-config --libs mysqlclient`

25.8.4.3. Написание поточных клиентов C API

Библиотека клиента почти безопасна для потоков. Самая большая проблема состоит в том что подпрограммы в sql/net_serv.cc, которые читают сокеты, не защищены от прерывания. Это было сделано с мыслью о том, что Вы можете хотеть иметь свой собственный аварийный сигнал, который может прервать долгое обращение к серверу. Если Вы устанавливаете обработчики прерывания для SIGPIPE, обработка сокета должна быть безопасной для потоков.

Чтобы программа не вылетела при прерывании соединения, MySQL блокирует SIGPIPE при первом обращении к mysql_library_init() , mysql_init() или mysql_connect(). Чтобы поставить свой обработчик SIGPIPE, сначала вызовите mysql_library_init() , а потом установите свой обработчик.

Если происходят ошибки undefined symbol при компоновке с libmysqlclient, в большинстве случаев это потому, что Вы не включили библиотеки потока.

Библиотека клиента безопасна для потоков на соединении. Вы можете позволить двум потокам совместно использовать то же самое соединение со следующими оговорками:

Вы должны знать следующее, если у Вас есть поток, который не создавал соединение с базой данных MySQL, но вызывает функции MySQL:

При вызове mysql_init() MySQL создает определенную для потока переменную, которая используется библиотекой отладки (в том числе). Если Вы вызываете функцию MySQL прежде, чем поток вызовет mysql_init(), у потока нет необходимых определенных для потока переменных, и Вы, вероятно, закончите с дампом памяти рано или поздно. Чтобы избежать проблем, Вы должны сделать следующее:

  1. Вызвать mysql_library_init() перед любыми другими функциями MySQL. Это не безопасно для потока, так что вызовите это прежде, чем потоки будут созданы, или защитите вызов с помощью mutex.

  2. Организуйте вызов mysql_thread_init() в обработчике потока прежде, чем вызвать любую функцию MySQL. Если Вы вызываете mysql_init(), она сама вызовет mysql_thread_init().
  3. В потоке вызовите mysql_thread_end() ДО pthread_exit(). Это освобождает память, используемую MySQL для переменных, определенных для потока.

Предыдущие примечания относительно mysql_init() также применимы к mysql_connect(), который вызывает mysql_init().

25.8.4.4 Запуск клиентских программ C API

Если после обновления Вы имете проблемы с собранными программами-клиентами, такие как Commands out of sync или дамп ядра, программы были, вероятно, собраны, используя старый заголовок или файлы библиотеки. В этом случае проверьте дату mysql.h и libmysqlclient.a. Повторно соберите программы с новыми заголовками и библиотеками. Перекомпиляция также может быть необходимой для программ, собранных с совместно используемыми библиотеками клиента, если изменился главный номер версии библиотеки (например, libmysqlclient.so.17 заменена на libmysqlclient.so.18).

Главный номер версии библиотеки определяет совместимость. Например, для libmysqlclient.so.18.1.0 главный номер версии 18. Поэтому библиотеки, поставленные с более новыми версиями MySQL, являются заменой для более старых версий, у которых есть тот же самый главный номер версии. Пока главная версия библиотеки та же самая, Вы можете обновить библиотеку, и старые приложения должны продолжать работать с ней.

Ошибки Undefined-reference могут произойти во время выполнения, когда Вы пытаетесь выполнить программу MySQL. Если они определяют символы, которые начинаются с mysql_ или указывают, что бибилотека libmysqlclient не может быть найдена, это означает, что Ваша система не может найти совместно используемую библиотеку libmysqlclient.so. Решение этой проблемы состоит в том, чтобы указать Вашей системе искать совместно используемые библиотеки в каталоге, где эта библиотека расположена. Используйте, какой-то из следующих методов, который подходящий для Вашей системы:

Если приложение скомпоновано со встроенной библиотекой сервера, то сообщения об ошибках во время выполнения укажут на libmysqld вместо libmysqlclient, но решение проблемы то же самое, как только что описано.

25.8.4.5. Версии сервера и библиотеки клиента C API

Строковая и числовая формы версии сервера MySQL доступны во время компиляции как значения макросов MYSQL_SERVER_VERSION и MYSQL_VERSION_ID, а во время выполнения как значения функций mysql_get_server_info() и mysql_get_server_version().

Версия библиотеки клиента MySQL зависит от типа дистрибутива, который предоставляет библиотеку:

25.8.5. Структуры данных C API

Этот раздел описывает структуры данных C API, кроме используемых для готовых команд.

Структура MYSQL_FIELD содержит члены, описанные в следующем списке. Определения применяются прежде всего для столбцов наборов результатов, таких как произведенные запросом SELECT. Структура MYSQL_FIELD также используется, чтобы обеспечить метаданные для для параметров OUT и INOUT возврата из хранимых процедур, выполненных, используя подготовленный запрос CALL. Для таких параметров у некоторых из членов структуры есть значение, отличающееся от значения для столбцов.

25.8.6. Обзор функций C API

Таблица 25.4. Имена и описания функций C API

Функция Описание
my_init() Инициализирует глобальные переменные и обработчик потоков в безопасных для потоков программах
mysql_affected_rows() Возвращает число строк, измененных/удаленных/вставленных последним запросом UPDATE, DELETE или INSERT
mysql_autocommit() Переключает режим autocommit вкл\выкл
mysql_change_user()Меняет пользователя и базу данных на открытом соединении
mysql_character_set_name() Возвратите имя набора символов по умолчанию для текущего соединения
mysql_client_find_plugin() Возвращает указатель на плагин
mysql_client_register_plugin()Регистрирует плагин
mysql_close()Закрывает соединение с сервером
mysql_commit()Передает транзакцию
mysql_connect() Связывается с сервером MySQL (функция устарела, используйте вместо нее mysql_real_connect() )
mysql_create_db() Создает базу данных (функция устарела, используйте оператор SQL CREATE DATABASE)
mysql_data_seek() Переходит на произвольный номер строки в наборе результатов запроса
mysql_debug() Делает DBUG_PUSH с данной строкой
mysql_drop_db() Удаляет базу данных (функция устарела, используйте оператор SQL DROP DATABASE)
mysql_dump_debug_info() Заставляет сервер записать отладочную информацию в журнал
mysql_eof() Определяет, была ли последняя строка набора результатов считана (функция устарела, вместо нее используются mysql_errno() или mysql_error())
mysql_errno() Возвращает код ошибки для последней вызванной функции MySQL
mysql_error() Возвращает сообщение об ошибке для последней вызванной функции MySQL
mysql_escape_string()Экранирует специальные символы в строке для использования в выражении SQL
mysql_fetch_field() Возвращает тип следующего поля таблицы
mysql_fetch_field_direct() Возвращает тип поля таблицы по номеру
mysql_fetch_fields() Возвращает массив всех структур полей
mysql_fetch_lengths() Возвращает длины всех столбцов в текущей строке
mysql_fetch_row() Возвращает следующую строку набора результатов
mysql_field_count() Возвращает число столбцов результата для запроса
mysql_field_seek() Помещает курсор в указанный столбец
mysql_field_tell() Возвращает позицию курсора, используемого для последнего запроса mysql_fetch_field()
mysql_free_result() Освобождает память, используемую набором результатов
mysql_get_character_set_info() Возвратите информацию о наборе символов по умолчанию
mysql_get_client_info() Информация о версии клиента как строка
mysql_get_client_version() Информация о версии клиента как целое число
mysql_get_host_info() Возвращает строку, описывающую соединение
mysql_get_option() Возвращает значение mysql_options()
mysql_get_proto_info() Возвращает версию протокола, используемую соединением
mysql_get_server_info() Возвращает номер версии сервера
mysql_get_server_version() Номер версии сервера как целое число
mysql_get_ssl_cipher()Возвращает текущий шифр SSL
mysql_hex_string() Кодирует строку в шестнадцатеричном формате
mysql_info() Информация о последнем выполненном запросе
mysql_init() Получает или инициализирует структуру MYSQL
mysql_insert_id() Возвращает ID, сгенерированный столбцом AUTO_INCREMENT для предыдущего запроса
mysql_kill()Уничтожает заданный поток
mysql_library_end()Завершает библиотеку MySQL C API
mysql_library_init() Запускает библиотеку MySQL C API
mysql_list_dbs() Возвращает имена баз данных, соответствующие простому регулярному выражению
mysql_list_fields() Возвращает имена полей, соответствующие простому регулярному выражению
mysql_list_processes() Возвращает список текущих потоков сервера
mysql_list_tables() Возвращает имена таблиц, соответствующие простому регулярному выражению
mysql_load_plugin()Загружает плагин
mysql_load_plugin_v()Загружает плагин
mysql_more_results() Проверяет, существуют ли еще результаты
mysql_next_result() Возвращает/начинает следующий результат, когда их много
mysql_num_fields() Возвращает число столбцов в наборе результатов
mysql_num_rows() Возвращает число строк в наборе результатов
mysql_options()Задает опции соединения для mysql_real_connect()
mysql_options4()Задает опции соединения для mysql_real_connect()
mysql_ping() Проверяет, работает ли соединение с сервером, повторно соединяясь по мере необходимости
mysql_plugin_options()Устанавливает опции плагина
mysql_query() Выполняет запрос SQL, определенный как законченная нулем строка
mysql_real_connect()Соединяется с сервером MySQL
mysql_real_escape_string() Экранирует специальные символы в строке для использования в запросе SQL, принимая во внимание текущий набор символов соединения
mysql_real_escape_string_quote() Экранирует специальные символы в строке для использования в запросе SQL, принимая во внимание текущий набор символов соединения и контекст, заключенный в кавычки
mysql_real_query() Выполняет запрос SQL, определенный как строка
mysql_refresh()Сбрасывает или перезапускает таблицы и кэши
mysql_reload() Предписывает серверу перезагрузить таблицы привилегий
mysql_reset_connection() Перезапускает соединение с новым статусом сессии
mysql_rollback()Откатывает транзакцию
mysql_row_seek() Переходит на смещение строки в наборе результатов, используя значение из mysql_row_tell()
mysql_row_tell()Возвращает позицию курсора в строке
mysql_select_db()Выбирает базу данных
mysql_server_end()Завершает библиотеку MySQL C API
mysql_server_init() Запускает библиотеку MySQL C API
mysql_session_track_get_first() Получает первую часть информации об изменении статуса сессии
mysql_session_track_get_next() Получает следующую часть информации об изменении статуса сессии
mysql_set_character_set() Задает набор символов по умолчанию для текущего соединения
mysql_set_local_infile_default() Устанавливает обработчик LOAD DATA LOCAL INFILE к его значениям по умолчанию
mysql_set_local_infile_handler() Устанавливает обработчик LOAD DATA LOCAL INFILE
mysql_set_server_option() Устанавливает опцию для соединения (например, multi-statements)
mysql_sqlstate() Возвращает код SQLSTATE для последней ошибки
mysql_ssl_set() Подготавливается установить соединение SSL с сервером
mysql_stat()Возвращает состояние сервера как строку
mysql_store_result() Передает полный набор результатов клиенту
mysql_thread_end()Завершает обработчик потока
mysql_thread_id() Возвращает ID текущего потока
mysql_thread_init() Инициализирует обработчик потока
mysql_thread_safe() Возвращает 1, если клиент собран как безопасный для потоков
mysql_use_result() Начинает построчное извлечение набора результатов
mysql_warning_count() Возвращает число предупреждений для предыдущего запроса SQL

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

  1. Инициализируйте библиотеку MySQL вызовом mysql_library_init(). Эта функция существует в обеих библиотеках, libmysqlclient и libmysqld, таким образом, это используется, создаете ли Вы регулярную программу-клиента, компонуя с флагом -libmysqlclient, или встроенное приложение сервера, компонуя с флагом -libmysqld.

  2. Инициализируйте обработчик соединения вызовом mysql_init() и соединитесь с сервером ( mysql_real_connect()).
  3. Сделайте запросы SQL и обработайте их результаты. Следующее обсуждение предоставляет больше информации о том, как это сделать.
  4. Закройте соединение с сервером MySQL вызовом mysql_close().
  5. Завершите использование библиотеки MySQL через mysql_library_end() .

Цель вызова mysql_library_init() и mysql_library_end() в том, чтобы обеспечить надлежащую инициализацию и завершение библиотеки MySQL. Для приложений, которые скомпонованы с библиотекой клиента, они предоставляют улучшенное управление памятью. Если Вы не вызвали mysql_library_end() , блок памяти остается выделенным. Это не увеличивает объем памяти, используемый приложением, но некоторые датчики утечки памяти будут жаловаться на это. Для приложений, которые скомпонованы со встроенным сервером, эти вызовы запускают и останавливают сервер.

В непоточной среде вызов mysql_library_init() может быть опущен, потому что mysql_init() вызовет это автоматически по мере необходимости. Однако, mysql_library_init() не безопасен для потока в мультипоточной среде. Вы должны или вызывать mysql_library_init() до порождения любых потоков, или иначе использования mutex, чтобы защитить поток, вызываете вы mysql_library_init() или косвенно через mysql_init(). Это должно быть сделано до любого другого вызова функции из библиотеки.

Чтобы соединиться с сервером, вызовите mysql_init(), чтобы инициализировать обработчик соединения, а затем mysql_real_connect() с этим обработчиком (наряду с другой информацией, такой как имя хоста, имя пользователя и пароль). Для соединения mysql_real_connect() устанавливает флаг reconnect (часть структуры MYSQL) в 1 в версиях API до 5.0.3 или в 0 в более новых. Значение 1 этого флага указывает на то, что если запрос не может быть выполнен из-за потерянного соединения, надо попытаться повторно соединиться с сервером перед отказом. Вы можете использовать опцию MYSQL_OPT_RECONNECT в mysql_options() чтобы управлять поведением пересоединения. Когда Вы закончите работу, закройте соединение вызовом mysql_close().

В то время как соединение является активным, клиент может послать запросы SQL серверу, используя mysql_query() или mysql_real_query(). Различие между этими функциями в том, что mysql_query() ожидает, что запрос будет определен как законченная нулем строка, тогда как mysql_real_query() ожидает обычную строку. Если строка содержит двоичные данные (которые могут включать нулевые байты), Вы должны использовать mysql_real_query().

Для не-SELECT запросов (например, INSERT, UPDATE, DELETE), Вы можете узнать, сколько строк было изменено (затронуто) вызовом mysql_affected_rows().

Для запросов SELECT Вы получаете выбранные строки в наборе результатов. Заметьте, что некоторые команды, подобные SELECT, тоже возвразают строки именно так. Это SHOW, DESCRIBE и EXPLAIN. Обработайте их так же, как SELECT .

Есть два способа для клиента обработать наборы результатов. Один путь состоит в том, чтобы получить весь набор результатов вызовом mysql_store_result(). Эта функция получает от сервера все строки, возвращенные запросом, и хранит их в клиенте. Второй путь в том, чтобы начать извлечение набора результатов построчно вызовом mysql_use_result() . Эта функция инициализирует извлечение, но фактически не получает строк от сервера.

В обоих случаях Вы получаете доступ к строкам через mysql_fetch_row() . С помощью mysql_store_result(), mysql_fetch_row() обращается к строкам, которые были ранее переданы с сервера. С mysql_use_result() mysql_fetch_row() фактически получает строку от сервера. Информация о размере данных в каждой строке доступна через вызов mysql_fetch_lengths().

После того, как Вы закончите с набором результатов, вызовите mysql_free_result(), чтобы освободить память, используемую для этого.

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

Преимущество mysql_store_result() в том, что все строки передаются клиенту, Вы не только можете получить доступ к строкам последовательно, Вы можете двигаться вперед-назад в использовании набора результатов, используя result set using mysql_data_seek() или mysql_row_seek() изменить текущую позицию строки в пределах набора результатов. Вы можете также узнать, сколько там строк через mysql_num_rows() . С другой стороны, требования к памяти для mysql_store_result() могут быть очень высоким для больших наборов результатов, и Вы, более вероятно, столкнетесь с проблемами.

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

API позволяет клиентам соответственно ответить на запросы получая строки только по мере необходимости), не зная, является ли запрос SELECT. Вы можете сделать это вызовом mysql_store_result() после каждого mysql_query() (или mysql_real_query() ). Если требование набора результатов успешно, запросом был SELECT и Вы можете читать строки. Если требование набора результатов терпит неудачу, вызовите mysql_field_count() , чтобы определить, состоял ли результат в том, что фактически ожидается. Если mysql_field_count() вернет 0, запрос не возвратил данных (указывает, что это был INSERT , UPDATE, DELETE и т.д.) и, как ожидалось, не возвратил строки. Если mysql_field_count() не 0, запрос должен был возвратить строки, но этого не сделал. Это указывает, что запрос SELECT был неудачным.

mysql_store_result() и mysql_use_result() позволяют Вам получить информацию о полях, которые составляют набор результатов (число, их имена и типы и т.д.). Вы можете получить доступ к информации последовательно, неоднократно вызывая calling mysql_fetch_field() или по номеру поля вызовом mysql_fetch_field_direct(). Текущая позиция курсора может быть изменена через mysql_field_seek(). Установка курсора затрагивает последующие вызовы mysql_fetch_field(). Вы можете также получить информацию для для всех полей вызовом mysql_fetch_fields().

Для обнаружения и сообщения об ошибках MySQL обеспечивает доступ к информации об ошибке посредством функций mysql_errno() и mysql_error(). Они возвращают код ошибки или сообщение об ошибке для последний раз вызванной функции, которая может потерпеть неудачу, позволяя Вам определить, когда ошибка произошла и что это было.

25.8.7. Описание функций C API

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

Функции, которые возвращают значение вообще, возвращают указатель или целое число. Если не определено иное, функции, возвращая указатель, возвращают значение не-NULL, чтобы указать на успех или NULL, чтобы указать на ошибку, а функции, возвращающие целое число, возвращают ноль, чтобы указать на успех или отличное от нуля значение, чтобы указать на ошибку. Отметьте, что "не 0" означает только это. Если функциональное описание не говорит иного, не проверяйте значения кроме ноля:

if (result)     /* correct */
   ... error ...
if (result < 0) /* incorrect */
   ... error ...
if (result == -1) /* incorrect */
   ... error ...

Когда функция возвращает ошибку, подраздел функционального описания Ошибки перечисляет возможные типы ошибок. Вы можете узнать что случилось, вызывая mysql_errno(). Строковое представление ошибки может быть получено с помощью mysql_error().

25.8.7.1. mysql_affected_rows()

my_ulonglong mysql_affected_rows(MYSQL *mysql)

Описание

mysql_affected_rows() может быть немедленно вызвана после выполнения запроса mysql_query() или mysql_real_query(). Это возвращает число строк, которые изменились, удалились или вставились последним запросом, если это был UPDATE, DELETE или INSERT. Для запросов SELECT mysql_affected_rows() работает аналогично mysql_num_rows() .

Для запроса UPDATE значение затронутых строк по умолчанию равно числу строк, фактически измененных. Если Вы определяете опцию CLIENT_FOUND_ROWS в mysql_real_connect() соединяясь с mysqld, значение затронутых строк равно числу найденных строк, то есть, соответствующих определению WHERE.

Для запроса REPLACE значение затронутых строк 2, если новая строка заменила старую, потому что в этом случае одна строка была вставлена после того, как дубликат был удален.

Для запросов INSERT ... ON DUPLICATE KEY UPDATE число затронутых строк для каждой обработанной строки 1, если строка вставлена как новая строка, 2, если существующая строка обновлена, и 0, если существующая строка оставлена в текущем состоянии. Если Вы определяете опцию CLIENT_FOUND_ROWS, значение затронутых строк 1 (не 0), если существующая строка была оставлена в ее текущем состоянии.

Для запросов CALL mysql_affected_rows() возвращает значение, которое возвратило бы для последнего запроса, выполненного в пределах хранимой процедуры, или 0 этот запрос вернул бы -1. В пределах процедуры Вы можете использовать ROW_COUNT() на уровне SQL, чтобы получить количество затронутых строк для отдельных запросов.

Возвращаемые значения

Целое число, больше чем ноль, указывает на число строк, обработанных или полученных. Ноль указывает, что никакие записи не были обновлены UPDATE, никакие строки не соответствовали WHERE или что никакой запрос еще не был выполнен. -1 указывает, что запрос вернул ошибку или что для запроса SELECT mysql_affected_rows() был вызван до запроса mysql_store_result().

Поскольку mysql_affected_rows() возвращает значение, Вы можете проверить на-1, сравнивая возвращаемое значение с (my_ulonglong)-1 (или (my_ulonglong)~0).

Ошибки

Нет.

Пример
char *stmt = "UPDATE products SET cost=cost*1.25 WHERE group=10";
mysql_query(&mysql,stmt);
printf("%ld products updated", (long) mysql_affected_rows(&mysql));

25.8.7.2. mysql_autocommit()

my_bool mysql_autocommit(MYSQL *mysql, my_bool mode)

Описание

Устанавливает режим autocommit в on, если mode 1, и в off, если mode 0.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

Нет.

25.8.7.3. mysql_change_user()

my_bool mysql_change_user(MYSQL *mysql, const char *user, const char *password, const char *db)

Описание

Изменяет пользователя и устанавливает базу данных, определенную db, в качестве базы данных по умолчанию для соединения mysql. В последующих запросах эта база данных будет значением по умолчанию для табличных ссылок, которые не включают явного спецификатора базы данных.

mysql_change_user() терпит неудачу, если пользователь не может быть авторизован или не имеет разрешения использовать базу данных. В этом случае пользователь и база данных не будут изменены.

Установите db в NULL, если Вы не хотите иметь базу данных значения по умолчанию.

Эта функция сбрасывает статус сессии, как будто сделано новое подключение с авторизацией. Это всегда выполняет ROLLBACK любых активных транзакций, удаляет все временные таблицы и отпирает все заблокированные таблицы. Системные переменные сеанса будут сброшены к значениям соответствующих глобальных системных переменных. Готовые запросы завершены, а переменные HANDLER закрыты. Блокировки, приобретенные с GET_LOCK() снимаются. Эти эффекты происходят, даже если пользователь не изменялся.

Чтобы сбросить статус соединения в более легкой манере, не изменяя пользователя, вызовите mysql_reset_connection().

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

То же самое, что Вы можете получить от mysql_real_connect(), плюс:

Пример
if (mysql_change_user(&mysql, "user", "password", "new_database")) {
   fprintf(stderr, "Failed to change user.  Error: %s\n",
           mysql_error(&mysql));
}

25.8.7.4. mysql_character_set_name()

const char *mysql_character_set_name(MYSQL *mysql)

Описание

Возвращает название набора символов по умолчанию для текущего соединения.

Возвращаемые значения

Имя набора символов по умолчанию.

Ошибки

Нет.

25.8.7.5. mysql_close()

void mysql_close(MYSQL *mysql)

Описание

Закрывает ранее открытое соединение. mysql_close() также освобождает дескриптор соединения, который указан mysql, если дескриптор был выделен автоматически mysql_init() или mysql_connect() .

Возвращаемые значения

Нет.

Ошибки

Нет.

25.8.7.6. mysql_commit()

my_bool mysql_commit(MYSQL *mysql)

Описание

Закрывает текущую транзакцию.

Действие этой функции зависит от значения системной переменной completion_type. В частности, если значение completion_type равно RELEASE (или 2), сервер выполняет сброс после прерывания транзакции и закрывает соединение клиента. Вызовите mysql_close() из программы, чтобы закрыть соединение со стороны клиента.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

Нет.

25.8.7.7. mysql_connect()

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

Описание

Эта функция устарела. Используйте вместо нее mysql_real_connect().

mysql_connect() пытается установить соединение с сервером баз данных MySQL на машине host. mysql_connect() должен завершиться успешно прежде, чем Вы сможете выполнить любую из других функций API, за исключением mysql_get_client_info().

Значения параметров те же самые, что и для mysql_real_connect() с тем различием, что параметр соединения может быть NULL. В этой ситуации C API выделяет память для структуры соединения автоматически и освобождает ее, когда Вы вызовете mysql_close() . Недостаток этого подхода: Вы не можете получить сообщение об ошибке, если связь прерывается. Чтобы получить информацию от mysql_errno() или mysql_error(), Вы должны обеспечить допустимый указатель MYSQL.

Возвращаемые значения

Аналогично mysql_real_connect().

Ошибки

Аналогично mysql_real_connect().

25.8.7.8. mysql_create_db()

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

Описание

Создает базу данных с именем, заданным в db.

Эта функция устарела, вместо нее используйте mysql_query() для выполнения запроса SQL CREATE DATABASE.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки
Пример
if (mysql_create_db(&mysql, "my_database")) {
   fprintf(stderr, "Failed to create new database.  Error: %s\n",
           mysql_error(&mysql));
}

25.8.7.9. mysql_data_seek()

void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset)

Описание

Позиционируется на произвольную строку в наборе результатов запроса. offset задает номер строки. Определите значение в диапазоне от 0 до mysql_num_rows(result)-1.

Эта функция требует, чтобы структура набора результатов содержала весь результат запроса, таким образом, mysql_data_seek() может использоваться только вместе с mysql_store_result() , но не с mysql_use_result().

Возвращаемые значения

Нет.

Ошибки

Нет.

25.8.7.10. mysql_debug()

void mysql_debug(const char *debug)

Описание

Делает DBUG_PUSH с заданной строкой. mysql_debug() пользуется библиотекой отладки Фреда Фиша. Чтобы использовать эту функцию, Вы должны собрать библиотеку клиента с поддержкой отладки.

Возвращаемые значения

Нет.

Ошибки

Нет.

Пример

Вызов, показанный здесь, заставляет библиотеку клиента генерировать файл трассировки в /tmp/client.trace на клиентской машине:

mysql_debug("d:t:O,/tmp/client.trace");

25.8.7.11. mysql_drop_db()

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

Описание

Удаляет базу данных с именем из параметра db.

Эта функция устарела. Предпочтительно использовать вместо нее mysql_query() для выполнения запроса SQL DROP DATABASE.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки
Пример
if (mysql_drop_db(&mysql, "my_database"))
   fprintf(stderr, "Failed to drop the database: Error: %s\n",
           mysql_error(&mysql));

25.8.7.12. mysql_dump_debug_info()

int mysql_dump_debug_info(MYSQL *mysql)

Описание

Предписывает серверу записать информацию об отладке в журнал ошибок. Соединенный пользователь должен иметь привилегию SUPER.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

25.8.7.13. mysql_eof()

my_bool mysql_eof(MYSQL_RES *result)

Описание

Эта функция устарела. mysql_errno() или mysql_error() может использоваться вместо нее.

mysql_eof() определяет, была ли последняя строка набора результатов считана.

Если Вы получаете набор результатов успешным вызовом mysql_store_result() , клиент получает весь набор данных. В этом случае mysql_fetch_row() вернет NULL, это всегда означает, что конец набора результатов был достигнут и не нужно вызывать mysql_eof(). Когда используется mysql_store_result() , mysql_eof() всегда возвращает true.

С другой стороны, если Вы используете mysql_use_result() , чтобы начать извлечение набора результатов, строки набора будут получены с сервера одна за другой по мере того, как Вы вызываете mysql_fetch_row() . Поскольку ошибка может произойти в соединении во время этого процесса, возвращаемое значение NULL из mysql_fetch_row() не обязательно означает, что конец набора результатов достигнут. В этом случае Вы можете использовать mysql_eof(), чтобы определить, что произошло. mysql_eof() возвращает ненулевое значение, если конец набора результатов был достигнут и ноль, если ошибка произошла.

Исторически mysql_eof() предшествует стандартным функциям ошибок MySQL mysql_errno() и mysql_error(). Поскольку эти функции ошибок предоставляют ту же самую информацию, их использование предпочтительнее mysql_eof(), которая устарела. Фактически они предоставляют больше информации, потому что mysql_eof() возвращает только булево значение, тогда как функции ошибок указывают на причину ошибки.

Возвращаемые значения

Ноль для успеха. Отличное от нуля, если конец набора результатов был достигнут.

Ошибки

Нет.

Пример

Следующий пример показывает, как Вы могли бы использовать mysql_eof():

mysql_query(&mysql,"SELECT * FROM some_table");
result = mysql_use_result(&mysql);
while((row = mysql_fetch_row(result))) {
  // do something with data
}
if (!mysql_eof(result))  // mysql_fetch_row() failed due to an error {
   fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
}

Однако, Вы можете достичь того же самого эффекта стандартными функциями ошибок MySQL:

mysql_query(&mysql,"SELECT * FROM some_table");
result = mysql_use_result(&mysql);
while((row = mysql_fetch_row(result))) {
  // do something with data
}
if (mysql_errno(&mysql))  // mysql_fetch_row() failed due to an error {
   fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
}

25.8.7.14. mysql_errno()

unsigned int mysql_errno(MYSQL *mysql)

Описание

Для соединения, определенного mysql, mysql_errno() возвращает код ошибки для последней вызванной функции API, которая может потерпеть неудачу. Возвращаемое значение 0, что никакой ошибки не произошло. Коды сообщений об ошибках клиента перечислены в заголовочном файле MySQL errmsg.h. Коды сообщений об ошибках сервера перечислены в mysqld_error.h. Ошибки также перечислены в приложении B. Ошибки, коды ошибок и типичные проблемы.

Некоторые функции такие, как mysql_fetch_row() , не устанавливают mysql_errno(), если они отработали нормально.

MySQL-специфичные коды ошибок, возвращенные mysql_errno(), отличаются от значений SQLSTATE, возвращенных mysql_sqlstate() . Например, клиент mysql выводит на экран ошибки, используя следующий формат, где 1146 значение mysql_errno() и '42S02' соответствующее значение mysql_sqlstate():

shell> SELECT * FROM no_such_table;
ERROR 1146 (42S02): Table 'test.no_such_table' doesn't exist
Возвращаемые значения

Значение кода ошибки для последнего вызова mysql_xxx(), если это потерпело неудачу. 0 означает, что никакая ошибка не произошла.

Ошибки

Нет.

25.8.7.15. mysql_error()

const char *mysql_error(MYSQL *mysql)

Описание

Для соединения, определенного mysql, mysql_error() возвращает законченную нулем строку, содержащую сообщение об ошибке для последней вызванной функции API, которая потерпела неудачу. Если функция не потерпела неудачу, возвращаемое значение mysql_error() может быть предыдущей ошибкой или пустой строкой, чтобы не указать ни на какую ошибку вообще.

Для функций, которые сбрасывают mysql_error(), любой из этих двух тестов может использоваться, чтобы проверить на ошибку:

if (*mysql_error(&mysql)) {
   // an error occurred
}

if (mysql_error(&mysql)[0]) {
   // an error occurred
}

Язык сообщений об ошибках клиента может быть изменен, повторно собирая библиотеку клиента MySQL. Вы можете выбрать сообщения об ошибках на нескольких различных языках. См. раздел 11.2. Установка языка сообщений об ошибках.

Возвращаемые значения

Законченная нулем строка символов, которая описывает ошибку. Пустая строка, если никакая ошибка не произошла.

Ошибки

Нет.

25.8.7.16. mysql_escape_string()

Не используйте эту функцию. mysql_escape_string() не имеет параметров, которые позволяют учитывать текущий набор символов или контекст в кавычках. Вместо этого применяйте mysql_real_escape_string_quote().

25.8.7.17. mysql_fetch_field()

MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)

Описание

Возвращает определение одного столбца набора результатов как структуру MYSQL_FIELD. Вызовите эту функцию неоднократно, чтобы получить информацию обо всех столбцах в наборе результатов. mysql_fetch_field() вернет NULL, когда полей больше нет.

mysql_fetch_field() сбрасывается, чтобы возвратить информацию о первом поле каждый раз, когда Вы выполняете новый запрос SELECT. Поле, которое вернет mysql_fetch_field() , также определяется вызовами mysql_field_seek() .

Если Вы вызывали mysql_query(), чтобы выполнить SELECT на таблице, но не вызвали mysql_store_result() , MySQL возвращает длину blob по умолчанию (8KB), если Вы вызываете mysql_fetch_field(), чтобы запросить длину поля типа BLOB. Размер 8 КБ выбран, потому что MySQL не знает максимальной длины для BLOB. Когда-нибудь это должно быть сделано конфигурируемым. Как только Вы получили набор результатов, field->max_length содержит длину самого большого значения для этого столбца в определенном запросе.

Возвращаемые значения

Структура MYSQL_FIELD для текущего столбца. NULL, если никаких столбцов нет.

Ошибки

Нет.

Пример
MYSQL_FIELD *field;

while((field = mysql_fetch_field(result)))
{
  printf("field name %s\n", field->name);
}

25.8.7.18. mysql_fetch_field_direct()

MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)

Описание

Учитывая номер поля fieldnr для столбца в пределах набора результатов, возвращает определение столбца как структуру MYSQL_FIELD. Используйте эту функцию, чтобы получить определение для произвольного столбца. Определите значение для fieldnr в диапазоне от 0 до mysql_num_fields(result)-1.

Возвращаемые значения

Структура MYSQL_FIELD для указанного столбца.

Ошибки

Нет.

Пример
unsigned int num_fields;
unsigned int i;
MYSQL_FIELD *field;

num_fields = mysql_num_fields(result);
for (i = 0; i < num_fields; i++) {
  field = mysql_fetch_field_direct(result, i);
  printf("Field %u is %s\n", i, field->name);
}

25.8.7.19. mysql_fetch_fields()

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)

Описание

Возвращает массив из структур MYSQL_FIELD для набора результатов. Каждая структура обеспечивает определение для одного столбца набора результатов.

Возвращаемые значения

Массив из структур MYSQL_FIELD для всех столбцов набора результатов.

Ошибки

Нет.

Пример
unsigned int num_fields;
unsigned int i;
MYSQL_FIELD *fields;

num_fields = mysql_num_fields(result);
fields = mysql_fetch_fields(result);
for (i = 0; i < num_fields; i++) {
  printf("Field %u is %s\n", i, fields[i].name);
}

25.8.7.20. mysql_fetch_lengths()

unsigned long *mysql_fetch_lengths(MYSQL_RES *result)

Описание

Возвращает длины столбцов текущей строки в пределах набора результатов. Если Вы планируете скопировать значения полей, эта информация о длине также полезна для оптимизации, потому что Вы можете избежать вызовов strlen(). Кроме того, если набор результатов содержит двоичные данные, Вы должны использовать эту функцию, чтобы определить размер данных, потому что strlen() возвращает неправильные результаты для любого поля, содержащего нулевые символы.

Длина для пустых столбцов и для столбцов, содержащих значения NULL = 0. Чтобы видеть, как отличить эти два случая, см. описание для mysql_fetch_row().

Возвращаемые значения

Массив unsigned long integer, представляющих размер каждого столбца (не включая любые заканчивающие нулевые байты). NULL, если ошибка произошла.

Ошибки

mysql_fetch_lengths() допустимо только для текущей строки набора результатов. Это возвращает NULL, если Вы вызываете это перед запросом mysql_fetch_row() или после получения всех строк в результате.

Пример
MYSQL_ROW row;
unsigned long *lengths;
unsigned int num_fields;
unsigned int i;

row = mysql_fetch_row(result);
if (row) {
   num_fields = mysql_num_fields(result);
   lengths = mysql_fetch_lengths(result);
   for (i = 0; i < num_fields; i++) {
     printf("Column %u is %lu bytes in length.\n", i, lengths[i]);
   }
}

25.8.7.21. mysql_fetch_row()

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

Описание

Получает следующую строку набора результатов. Когда используется после mysql_store_result() , mysql_fetch_row() вернет NULL, если нет больше строк. Когда используется после mysql_use_result(), mysql_fetch_row() вернет NULL, когда нет больше строк или произошла ошибка.

Число значений в строке дает mysql_num_fields(result). Если row хранит возвращаемое значение от вызова mysql_fetch_row() , к указателям на значения получают доступ как row[0] до row[mysql_num_fields(result)-1]. Значения NULL в строке обозначены как указатели NULL.

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

Возвращаемые значения

Структура MYSQL_ROW для следующей строки. NULL, если нет больше строк или произошла ошибка.

Ошибки

Ошибки не сброшены между вызовами mysql_fetch_row() .

Пример
MYSQL_ROW row;
unsigned int num_fields;
unsigned int i;

num_fields = mysql_num_fields(result);
while ((row = mysql_fetch_row(result))) {
  unsigned long *lengths;

  lengths = mysql_fetch_lengths(result);
  for (i = 0; i < num_fields; i++) {
    printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL");
  }
  printf("\n");
}

25.8.7.22. mysql_field_count()

unsigned int mysql_field_count(MYSQL *mysql)

Описание

Возвращает число столбцов для нового запроса на соединении.

Нормальная эксплуатация этой функции: когда mysql_store_result() возвращает NULL и таким образом у Вас нет никакого указателя на набор результатов. В этом случае Вы можете вызвать mysql_field_count() , чтобы определить mysql_store_result() должен был привести к непустому результату. Это позволяет программе-клиенту предпринять надлежащие меры, не зная, был ли запрос SELECT (или подобным). Пример, показанный здесь, иллюстрирует, как это может быть сделано.

Возвращаемые значения

Число типа unsigned integer представляющее число столбцов в наборе результатов.

Ошибки

Нет.

Пример
MYSQL_RES *result;
unsigned int num_fields;
unsigned int num_rows;

if (mysql_query(&mysql,query_string)) {
   // error
}
else // query succeeded, process any data returned by it
{
  result = mysql_store_result(&mysql);
  if (result)  // there are rows {
     num_fields = mysql_num_fields(result);
     // retrieve rows, then call mysql_free_result(result)
  }
  else  // mysql_store_result() returned nothing; should it have?
  {
    if (mysql_field_count(&mysql) == 0) {
       // query does not return data
       // (it was not a SELECT)
       num_rows = mysql_affected_rows(&mysql);
    }
    else // mysql_store_result() should have returned data
    {
      fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
    }
  }
}

Альтернатива должна заменить mysql_field_count(&mysql) на mysql_errno(&mysql) . В этом случае Вы проверяете непосредственно на ошибку из mysql_store_result() вместо того, чтобы делать выводы из значения mysql_field_count() , был ли запрос SELECT .

25.8.7.23. mysql_field_seek()

MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)

Описание

Устанавливает курсор на указанное смещение. Следующий вызов mysql_fetch_field() получает определение столбца, связанного с этим смещением. Чтобы перейти на начало строки, задайте offset = 0.

Возвращаемые значения

Предыдущее значение расположения курсора.

Ошибки

Нет.

25.8.7.24. mysql_field_tell()

MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)

Описание

Возвращает позицию курсора, используемого для последнего вызова mysql_fetch_field() . Это значение может использоваться в качестве параметра mysql_field_seek() .

Возвращаемые значения

Текущая позиция курсора.

Ошибки

Нет.

25.8.7.25. mysql_free_result()

void mysql_free_result(MYSQL_RES *result)

Описание

Освобождает память, выделенную для набора результатов mysql_store_result() , mysql_use_result(), mysql_list_dbs() и т. д. Когда Вы закончили работу с набором результатов, Вы должны освободить память, которую это использует, вызывая mysql_free_result() . Не пытайтесь получить доступ к набору результатов после освобождения памяти!

Возвращаемые значения

Нет.

Ошибки

Нет.

25.8.7.26. mysql_get_character_set_info()

void mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET_INFO *cs)

Описание

Эта функция предоставляет информацию о наборе символов клиента по умолчанию. Набор символов по умолчанию может быть изменен с помощью функции mysql_set_character_set().

Пример

Этот пример показывает, которые доступны в структуре MY_CHARSET_INFO:

if (!mysql_set_character_set(&mysql, "utf8")) {
   MY_CHARSET_INFO cs;

   mysql_get_character_set_info(&mysql, &cs);
   printf("character set information:\n");
   printf("character set+collation number: %d\n", cs.number);
   printf("character set name: %s\n", cs.name);
   printf("collation name: %s\n", cs.csname);
   printf("comment: %s\n", cs.comment);
   printf("directory: %s\n", cs.dir);
   printf("multi byte character min. length: %d\n", cs.mbminlen);
   printf("multi byte character max. length: %d\n", cs.mbmaxlen);
}

25.8.7.27. mysql_get_client_info()

const char *mysql_get_client_info(void)

Описание

Возвращает строку, которая представляет версию библиотеки клиента MySQL; например, "8.0.1".

Функциональное значение: версия MySQL или Connector/C, которую предоставляет библиотека клиента. Для получения дополнительной информации, см. раздел 25.8.4.5, Версии сервера и библиотеки клиентов C API.

Возвращаемые значения

Строка символов, которая представляет версию библиотеки клиента MySQL.

Ошибки

Нет.

25.8.7.28. mysql_get_client_version()

unsigned long mysql_get_client_version(void)

Описание

Возвращает целое число, которое представляет версию библиотеки клиента MySQL. У значения есть формат XYYZZ, где X главный номер версии, YY уровень выпуска (или незначительная версия) и ZZ субверсия в пределах уровня выпуска:

major_version*10000 + release_level*100 + sub_version

Например, версия "8.0.1" возвращается как 80001.

Возвращаемые значения

Целое число, которое представляет версию библиотеки клиента MySQL.

Ошибки

Нет.

25.8.7.29. mysql_get_host_info()

const char *mysql_get_host_info(MYSQL *mysql)

Описание

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

Возвращаемые значения

Строка символов, представляющая имя хоста сервера и тип подключения.

Ошибки

Нет.

25.8.7.30. mysql_get_option()

int mysql_get_option(MYSQL *mysql, enum mysql_option option, const void *arg)

Описание

Возвращает текущее значение опций, которые можно задать, используя mysql_options() . Значение должно быть обработано как "только для чтения".

Аргумент option это опция, для которой Вы хотите узнать ее значение. Параметр arg указатель на переменную, в которой можно сохранить значение опции. arg должен быть указателем на переменную типа, подходящего для аргумента option. Следующяя таблица показывает, какие переменные подходят для каждого значения option.

Тип arg Допустимые значения option
unsigned int MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_PROTOCOL, MYSQL_OPT_READ_TIMEOUT, MYSQL_OPT_RETRY_COUNT, MYSQL_OPT_WRITE_TIMEOUT
unsigned long MYSQL_OPT_MAX_ALLOWED_PACKET, MYSQL_OPT_NET_BUFFER_LENGTH
my_bool MYSQL_ENABLE_CLEARTEXT_PLUGIN, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, MYSQL_OPT_COMPRESS, MYSQL_OPT_GUESS_CONNECTION, MYSQL_OPT_LOCAL_INFILE, MYSQL_OPT_RECONNECT, MYSQL_OPT_USE_EMBEDDED_CONNECTION, MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_SECURE_AUTH
const char * MYSQL_DEFAULT_AUTH, MYSQL_OPT_BIND, MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CAPATH , MYSQL_OPT_SSL_CERT, MYSQL_OPT_SSL_CIPHER, MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH, MYSQL_OPT_SSL_KEY, MYSQL_OPT_SSL_MODE, MYSQL_OPT_TLS_VERSION, MYSQL_PLUGIN_DIR, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP, MYSQL_SERVER_PUBLIC_KEY, MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_SET_CLIENT_IP, MYSQL_SHARED_MEMORY_BASE_NAME
cannot be queried (error is returned) MYSQL_INIT_COMMAND, MYSQL_OPT_CONNECT_ATTR_DELETE, MYSQL_OPT_CONNECT_ATTR_RESET, MYSQL_OPT_NAMED_PIPE
Возвращаемые значения

Ноль для успеха. Отличнок от нуля, если ошибка произошла: это происходит для значений option, которые не могут быть запрошены.

Пример

Следующий вызов проверяет опцию MYSQL_OPT_RECONNECT. После того, как вызов отработает успешно, значение reconnect будет true или false, чтобы указать, включено ли автоматическое пересоединение.

my_bool reconnect;
if (mysql_get_option(mysql, MYSQL_OPT_RECONNECT, &reconnect))
   fprintf(stderr, "mysql_get_options() failed\n");

25.8.7.31. mysql_get_proto_info()

unsigned int mysql_get_proto_info(MYSQL *mysql)

Описание

Возвращает версию протокола, используемую текущим соединением.

Возвращаемые значения

Число типа unsigned integer, представляющее версию протокола, который используется текущим соединением.

Ошибки

Нет.

25.8.7.32. mysql_get_server_info()

const char *mysql_get_server_info(MYSQL *mysql)

Описание

Возвращает строку, которая представляет версию сервера MySQL, например, "8.0.1".

Возвращаемые значения

Строка символов, которая представляет версию сервера MySQL.

Ошибки

Нет.

25.8.7.33. mysql_get_server_version()

unsigned long mysql_get_server_version(MYSQL *mysql)

Описание

Возвращает целое число, которое представляет версию сервера MySQL. У значения есть формат XYYZZ, где X главный номер версия, YY уровень выпуска (или незначительная версия) и ZZ субверсия в пределах уровня выпуска:

major_version*10000 + release_level*100 + sub_version

Например, "8.0.1" возвращается как 80001.

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

Возвращаемые значения

Целое число, которое представляет версию сервера MySQL.

Ошибки

Нет.

25.8.7.34. mysql_get_ssl_cipher()

const char *mysql_get_ssl_cipher(MYSQL *mysql)

Описание

mysql_get_ssl_cipher() возвращает шифр шифрования, используемый для данного соединения с сервером. mysql представляет собой обработчик соединения, возвращенный из mysql_init().

Возвращаемые значения

Строка, называющая шифр шифрования, используемый для соединения, или NULL, если никакой шифр не используется.

25.8.7.35. mysql_hex_string()

unsigned long mysql_hex_string(char *to, const char *from, unsigned long length)

Описание

Эта функция создает правильную строку SQL для использования в SQL-запросе. См. раздел 10.1.1. Строки литералов для подробностей.

Строка в параметре from будет закодирована в шестнадцатеричном формате, с каждым символом, закодированным как две шестнадцатеричных цифры. Результат помещен в параметр to, сопровождаемый завершающим нулевым байтом.

Строка, на которую указывает from должна быть length байт в длину. Вы должны выделить для to буфер, как минимум, length*2+1 байт длиной. Когда mysql_hex_string() сработает, в to будет законченная нулем строка. Возвращаемое значение: длина закодированной строки, не включая заканчивающий ее нулевой байт.

Возвращаемое значение может быть помещено в запрос SQL, используя также формат X'value' или 0xvalue. Однако, возвращаемое значение не включает X'...' или 0x.

Пример
char query[1000],*end;

end = strmov(query,"INSERT INTO test_table values(");
end = strmov(end,"X'");
end += mysql_hex_string(end,"What is this",12);
end = strmov(end,"',X'");
end += mysql_hex_string(end,"binary data: \0\r\n",16);
end = strmov(end,"')");
if (mysql_real_query(&mysql,query,(unsigned int) (end - query))) {
   fprintf(stderr, "Failed to insert row, Error: %s\n",
           mysql_error(&mysql));
}

Функция strmov(), используемая в примере, включена в библиотеку libmysqlclient и работает как strcpy(), но возвращает указатель на заканчивающий нуль первого параметра.

Возвращаемые значения

Длина закодированной строки, которая помещена в to, не включая заканчивающий нулевой символ.

Ошибки

Нет.

25.8.7.36. mysql_info()

const char *mysql_info(MYSQL *mysql)

Описание

Получает строку, предоставляющую информацию о последнем выполненном запросе, но только для запросов, перечисленных здесь. Для других mysql_info() вернет NULL. Формат строки изменяется в зависимости от типа запроса. Числа только иллюстративны, строка содержит значения, подходящие для запроса.

mysql_info() вернет не NULL для INSERT ... VALUES многострочной формы запроса (то есть, только если определен список значений).

Возвращаемые значения

Строка символов о последнем выполненном запросе. NULL, если никакая информация недоступна.

Ошибки

Нет.

25.8.7.37. mysql_init()

MYSQL *mysql_init(MYSQL *mysql)

Описание

Выделяет или инициализирует объект MYSQL, подходящий для mysql_real_connect() . Если mysql = NULL, функция выделяет, инициализирует и возвращает новый объект. Иначе, объект будет инициализирован, а адрес объекта возвращен. Если mysql_init() выделяет новый объект, он будет освобожден, когда mysql_close() вызывается для закрытия соединения.

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

Возвращаемые значения

Инициализированный дескриптор MYSQL*. NULL, если было недостаточно памяти, чтобы выделить новый объект.

Ошибки

В случае нехватки памяти вернется NULL.

25.8.7.38. mysql_insert_id()

my_ulonglong mysql_insert_id(MYSQL *mysql)

Описание

Возвращает значение, произведенное для столбца AUTO_INCREMENT предыдущим запросом INSERT или UPDATE. Используйте эту функцию после того, как Вы применили INSERT к таблице, которая содержит поле AUTO_INCREMENT, или использовали INSERT или UPDATE, чтобы установить значение столбца с LAST_INSERT_ID(expr).

Возвращаемое значение mysql_insert_id() всегда ноль, если явно не обновлено при одном из следующих условий:

Возвращаемое значение mysql_insert_id() может быть упрощено до следующей последовательности:

  1. Если есть столбец AUTO_INCREMENT, и автоматически произведенное значение было успешно вставлено, вернет первое такое значение.

  2. Если LAST_INSERT_ID(expr) была в запросе, вернет expr, даже если в таблице был столбец AUTO_INCREMENT.
  3. Возвращаемое значение изменяется в зависимости от используемого запроса. Когда функция вызвана после INSERT :

    Когда функция вызвана после INSERT ... ON DUPLICATE KEY UPDATE:

mysql_insert_id() вернет 0, если предыдущий запрос не использует AUTO_INCREMENT. Если Вы должны сохранить значение для последующего неспешного потребления, убедитесь, что вызвали mysql_insert_id() сразу после запроса, который производит значение.

Значение mysql_insert_id() затронуто только запросами, сделанными в пределах текущего соединения клиента. Это не затронуто запросами, сделанными другими клиентами.

SQL-функция LAST_INSERT_ID() будет содержать значение первого автоматически произведенного значения, которое было успешно вставлено. LAST_INSERT_ID() не сбрасывается между запросами, потому что значение этой функции поддерживается сервером. Другое отличие от mysql_insert_id() в том, что LAST_INSERT_ID() не обновляется, если Вы устанавливаете столбец AUTO_INCREMENT к определенному неспециальному значению.

mysql_insert_id() вернет 0 после команды CALL для хранимой процедуры, которая производит значение AUTO_INCREMENT, потому что в этом случае mysql_insert_id() относится к CALL, а не запросу в пределах процедуры. В пределах процедуры Вы можете использовать LAST_INSERT_ID() на уровне SQL, чтобы получить значение AUTO_INCREMENT.

Причина различий между LAST_INSERT_ID() и mysql_insert_id() в том, что LAST_INSERT_ID() удобней в скриптах, в то время как mysql_insert_id() пытается предоставить более точную информацию о том, что происходит со столбцом AUTO_INCREMENT.

Возвращаемые значения

Описаны в предыдущем обсуждении.

Ошибки

25.8.7.39. mysql_kill()

int mysql_kill(MYSQL *mysql, unsigned long pid)

Описание

mysql_kill() устарела и будет удалена в будущей версии MySQL. Вместо этого используйте mysql_query() для выполнения запроса KILL.

Просит сервер уничтожить поток, определенный pid.

mysql_kill() не может обработать значения больше, чем 32 бита, но чтобы принять меры против уничтожения неправильного потока, возвращает ошибку в случаях:

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла./p>

Ошибки

25.8.7.40. mysql_library_end()

void mysql_library_end(void)

Описание

Эта функция завершает библиотеку MySQL. Вызовите ее, когда Вы завершаете пользование библиотекой (например, после отсоединения от сервера). Действия, предпринятые вызовом, зависят от того, скомпоновано ли Ваше приложение с библиотекой клиента MySQL, или MySQL использует встроенную библиотеку сервера. Для программы клиента, скомпонованной библиотекой libmysqlclient флагом -lmysqlclient, mysql_library_end() выполняет некоторое управление памятью, чтобы ее очистить. Для встроенного приложения сервера, скомпонованного с библиотекой libmysqld посредством флага -lmysqld, mysql_library_end() закрывает встроенный сервер.

25.8.7.41. mysql_library_init()

int mysql_library_init(int argc, char **argv, char **groups)

Описание

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

После того, как Ваше приложение завершило использование библиотеки MySQL, вызовите mysql_library_end().

Выбор того, действует ли приложение в качестве клиента или использует встроенный сервер, зависит от того, используете ли Вы библиотеку libmysqlclient или libmysqld во время компоновки.

Аргументы argc и argv походят на параметры main() и позволяют передать опции встроенному серверу. Для удобства argc может быть 0, если нет никаких параметров командной строки серверу. Это обычный случай для приложений, предназначенных для использования только в качестве регулярных (невстроенных) клиентов, так что вызов обычно пишется как mysql_library_init(0, NULL, NULL):

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

int main(void)
{
  if (mysql_library_init(0, NULL, NULL)) {
     fprintf(stderr, "could not initialize MySQL library\n");
     exit(1);
  }
  /* Use any MySQL API functions here */
  mysql_library_end();
  return EXIT_SUCCESS;
}

Когда параметры нужно передать (argc больше 0), первый элемент argv игнорируется (он как, правило, содержит имя программы). mysql_library_init() делает копию параметров, таким образом, безопасно разрушить argv или groups после вызова.

Для встраиваемых приложений, если Вы хотите соединиться с внешним сервером, не запуская встроенный сервер, Вы должны определить отрицательную величину для argc.

Параметр groups массив строк, которые указывают на группы в файлах опций, из которых можно считать параметры. Заключительный вход в массиве всегда NULL. Для удобства если groups NULL, группы [server] и [embedded] используются по умолчанию.

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

static char *server_args[] = {
  "this_program", /* this string is not used */
  "--datadir=.",
  "--key_buffer_size=32M"
};

static char *server_groups[] = {"embedded", "server",
                                "this_program_SERVER",
                                (char *)NULL};

int main(void)
{
  if (mysql_library_init(sizeof(server_args) / sizeof(char *),
     server_args, server_groups)) {
     fprintf(stderr, "could not initialize MySQL library\n");
     exit(1);
  }
  /* Use any MySQL API functions here */
  mysql_library_end();
  return EXIT_SUCCESS;
}
Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

25.8.7.42. mysql_list_dbs()

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

Описание

Возвращает набор результатов, состоящий из имен баз данных на сервере, которые соответствуют простому регулярному выражению, определенному параметром wild. Он может содержать подстановочные символы % или _, или может быть NULL, чтобы соответствовать всем базам данных. Запрос mysql_list_dbs() подобен выполнению запроса SHOW DATABASES [LIKE wild].

Вы должны освободить набор результатов с помощью mysql_free_result() .

Возвращаемые значения

Набор результатов MYSQL_RES для успеха. NULL, если ошибка произошла.

Ошибки

25.8.7.43. mysql_list_fields()

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

Описание

mysql_list_fields() устарела и будет удалена в будущей версии MySQL. Вместо этого используйте mysql_query() для выполнения запроса SHOW COLUMNS .

Возвращает пустой набор результатов, для которого метаданные предоставляют информацию о столбцах в данной таблице, которые соответствуют простому регулярному выражению, определенному параметром wild. Он может содержать подстановочные символы % или _, или может быть NULL, чтобы соответствовать всем полям. Вызов mysql_list_fields() подобен выполнению запроса SHOW COLUMNS FROM tbl_name [LIKE wild].

Предпочтительно использовать SHOW COLUMNS FROM tbl_name вместо mysql_list_fields().

Вы должны освободить набор результатов с помощью mysql_free_result().

Возвращаемые значения

Набор результатов MYSQL_RES для успеха. NULL, если ошибка произошла.

Ошибки
Пример
int i;

MYSQL_RES *tbl_cols = mysql_list_fields(mysql, "mytbl", "f%");
unsigned int field_cnt = mysql_num_fields(tbl_cols);
printf("Number of columns: %d\n", field_cnt);
for (i=0; i < field_cnt; ++i) {
  /* col describes i-th column of the table */
  MYSQL_FIELD *col = mysql_fetch_field_direct(tbl_cols, i);
  printf ("Column %d: %s\n", i, col->name);
}
mysql_free_result(tbl_cols);

25.8.7.44. mysql_list_processes()

MYSQL_RES *mysql_list_processes(MYSQL *mysql)

Описание

mysql_list_processes() устарела и будет удалена в будущей версии MySQL. Вместо нее используйте mysql_query() для выполнения запроса SHOW PROCESSLIST.

Возвращает набор результатов, описывающий текущие потоки сервера. Это тот же самый вид информации, о котором сообщает команда mysqladmin processlist или запрос SHOW PROCESSLIST.

Вы должны освободить набор результатов с помощью mysql_free_result() .

Возвращаемые значения

Набор результатов MYSQL_RES для успеха. NULL, если ошибка произошла.

Ошибки

25.8.7.45. mysql_list_tables()

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

Описание

Возвращает набор результатов, состоящий из имен таблиц в текущей базе данных, которые соответствуют простому регулярному выражению, определенному параметром wild. Он может содержать подстановочные символы % или _, или быть NULL, чтобы соответствовать всем таблицам. Запрос mysql_list_tables() аналогичен вызову SHOW TABLES [LIKE wild].

Вы должны освободить набор результатов с помощью mysql_free_result() .

Возвращаемые значения

Набор результатов MYSQL_RES для успеха. NULL, если ошибка произошла.

Ошибки

25.8.7.46. mysql_more_results()

my_bool mysql_more_results(MYSQL *mysql)

Описание

Эта функция используется, когда Вы выполняете много запросов, определенных как единственная строка, или когда Вы выполняете запросы CALL, которые могут возвратить несколько наборов результатов.

mysql_more_results() истина, если несколько результатов поступает из выполняемого в настоящее время запроса, в этой ситуации приложение должно вызывать mysql_next_result() для получения результатов.

Возвращаемые значения

TRUE (1), если существует много результатов. FALSE (0), если это не так.

В большинстве случаев Вы можете вместо этого вызвать mysql_next_result() , чтобы проверить, существует ли больше результатов и начать их извлечение, если они есть.

Ошибки

Нет.

25.8.7.47. mysql_next_result()

int mysql_next_result(MYSQL *mysql)

Описание

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

mysql_next_result() читает следующий результат и возвращает состояние, чтобы указать, существуют ли еще результаты. Если mysql_next_result() возвращает ошибку, результатов больше нет.

Перед каждым вызовом mysql_next_result() Вы должны вызвать mysql_free_result() для текущего запроса, если этот запрос вернул набор результатов (а не только состояние результата).

После вызова mysql_next_result() состояние соединения как будто Вы вызвали mysql_real_query() или mysql_query() для следующего запроса. Это означает, что Вы можете вызывать mysql_store_result(), mysql_warning_count(), mysql_affected_rows() и т. п.

Если Ваша программа использует вызов CALL, чтобы выполнить хранимые процедуры, флаг CLIENT_MULTI_RESULTS должен быть включен. Это потому, что каждый CALL возвращает результат, чтобы указать на состояние, в дополнение к любым наборам результатов, которые могли бы быть возвращены запросами, выполненными в пределах процедуры. Поскольку CALL может возвращать много наборов результатов, обработайте их вызывая в цикле mysql_next_result(), чтобы определить, есть ли еще результаты.

CLIENT_MULTI_RESULTS может быть включен явно, когда Вы вызываете mysql_real_connect(), передавая флаг непосредственно, или неявно передачей флага CLIENT_MULTI_STATEMENTS (который также включает CLIENT_MULTI_RESULTS). CLIENT_MULTI_RESULTS включен по умолчанию.

Также возможно проверить, есть ли больше результатов, вызывая mysql_more_results() . Однако, эта функция не изменяет статус соединения, так что, если это возвращает истину, Вы все еще должны вызвать mysql_next_result() , чтобы добраться до следующего результата.

Возвращаемые значения
Успешно, но больше результатов нет
Возвращаемое значениеОписание
0Успешно и есть еще результаты
-1
>0Ошибка произошла
Ошибки

25.8.7.48. mysql_num_fields()

unsigned int mysql_num_fields(MYSQL_RES *result)

Чтобы применить аргумент MYSQL*, используйте unsigned int mysql_field_count(MYSQL *mysql).

Описание

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

Возвращаемые значения

Число типа unsigned integer, представляющее числ о столбцов в наборе результатов.

Ошибки

Нет.

Пример
MYSQL_RES *result;
unsigned int num_fields;
unsigned int num_rows;

if (mysql_query(&mysql,query_string)) {
   // error
}
else // query succeeded, process any data returned by it
{
  result = mysql_store_result(&mysql);
  if (result)  // there are rows {
     num_fields = mysql_num_fields(result);
     // retrieve rows, then call mysql_free_result(result)
  }
  else  // mysql_store_result() returned nothing; should it have?
  {
    if (mysql_errno(&mysql)) {
       fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
    }
    else if (mysql_field_count(&mysql) == 0) {
      // query does not return data
      // (it was not a SELECT)
      num_rows = mysql_affected_rows(&mysql);
    }
  }
}

Альтернатива (если Вы знаете, что Ваш запрос должен был возвратить набор результатов): заменить на вызов mysql_errno(&mysql) с проверкой на то, что mysql_field_count(&mysql) возвращает 0. Это происходит, только если что-то пошло не так, как надо.

25.8.7.49. mysql_num_rows()

my_ulonglong mysql_num_rows(MYSQL_RES *result)

Описание

Возвращает число строк в наборе результатов.

Использование mysql_num_rows() зависит от того, используете ли Вы mysql_store_result() или mysql_use_result(), чтобы получить набор результатов. Если Вы используете mysql_store_result(), mysql_num_rows() может быть немедленно вызван. Если Вы используете mysql_use_result() , mysql_num_rows() не возвращает правильное значение, пока все строки в наборе результатов не будут получены.

mysql_num_rows() предназначен для использования с запросами, которые возвращают набор результатов, таких как SELECT . Для запросов наподобие INSERT, UPDATE или DELETE, число затронутых строк может быть получено с помощью mysql_affected_rows().

Возвращаемые значения

Число строк в наборе результатов.

Ошибки

Нет.

25.8.7.50. mysql_options()

int mysql_options(MYSQL *mysql, enum mysql_option option, const void *arg)

Описание

Может использоваться, чтобы установить дополнительные опции соединения и затрагивает поведение соединения. Эта функция может быть вызвана многократно, чтобы установить несколько опций. Чтобы получить значения опции, используйте mysql_get_option() .

Вызывайте mysql_options() после mysql_init(), но перед mysql_connect() или mysql_real_connect().

Аргумент option это опция, которую Вы хотите установить. Параметр arg значение для опции. Если опция целое число, определите указатель на значение целого числа как arg.

Следующий список описывает возможные варианты опций, их эффект, и как arg используется для каждой опции. Несколько из опций применяются только, когда приложение скомпоновано со встроенной библиотекой сервера libmysqld и неприменима для приложений, скомпонованных с библиотекой клиента libmysqlclient. Для описаний опции, которые указывают, что arg не использован, его значение не важно, обычно это 0 для правильного вызова функции.

Группа client всегда читается, если Вы используете MYSQL_READ_DEFAULT_FILE или MYSQL_READ_DEFAULT_GROUP.

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

ОпцияОписание
character-sets-dir=dir_name Каталог, где наборы символов установлены.
compress Использовать сжатый протокол клиент-сервер.
connect-timeout=seconds Тайм-аут соединения в секундах. На Linux этот тайм-аут также используется для того, чтобы ждать первого ответа от сервера.
database=db_name Соединиться с этой базой данных, если никакая база данных не была определена в команде соединения.
debugОпции отладки.
default-character-set=charset_name Набор символов, чтобы использовать по умолчанию.
disable-local-infile Отключить использование LOAD DATA LOCAL INFILE.
enable-cleartext-plugin Включить плагин mysql_clear_password.
host=host_name Имя хоста по умолчанию.
init-command=stmt Запрос, который надо выполнить, соединяясь с сервером MySQL. Автоматически повторно выполнен, если пересоединение происходит.
interactive-timeout=seconds Аналогично указанию CLIENT_INTERACTIVE в mysql_real_connect() .
local-infile[={0|1}] Если никакой параметр не задан или параметр отличен от нуля, включить использование LOAD DATA LOCAL , иначе выключить.
max_allowed_packet=bytes Максимальный размер пакета, который клиент может считать с сервера.
multi-queries, multi-results Разрешить множественные наборы результатов для запросов или хранимых процедур.
multi-statements Позволить клиенту посылать много запросов в единственной строке (отделенных символом ;).
password=password Пароль по умолчанию.
pipe Использовать именованные каналы, чтобы соединиться с сервером MySQL под Windows.
port=port_num Порт по умолчанию.
protocol={TCP|SOCKET|PIPE|MEMORY} Протокол, чтобы использовать, соединяясь с сервером.
return-found-rows Предписывает mysql_info() вернуть число найденных строк вместо обновленных строк, используя UPDATE.
shared-memory-base-name=name Имя совместно используемой памяти, чтобы соединиться с сервером.
socket={file_name| pipe_name}Файл сокета по умолчанию.
ssl-ca=file_name Файл центра сертификации.
ssl-capath=dir_name Каталог центра сертификации.
ssl-cert=file_name Файл сертификата.
ssl-cipher=cipher_list Допустимые шифры SSL.
ssl-key=file_name Файл ключа.
timeout=seconds Аналогично connect-timeout.
userПользователь по умолчанию.

timeout был заменен connect-timeout, но timeout все еще поддержан для обратной совместимости.

Возвращаемые значения

Ноль для успеха. Отличное от нуля, если Вы определяете неизвестную опцию.

Пример

Следующий вызов mysql_options() предписывает использование сжатия в протоколе клиент-сервер, заставляет считать опции из группы [odbc] файла опций my.cnf и отключает режим autocommit:

MYSQL mysql;

mysql_init(&mysql);
mysql_options(&mysql,MYSQL_OPT_COMPRESS,0);
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc");
mysql_options(&mysql,MYSQL_INIT_COMMAND,"SET autocommit=0");
if (!mysql_real_connect(&mysql,"host","user","passwd","database",
    0,NULL,0)) {
   fprintf(stderr, "Failed to connect to database: Error: %s\n",
   mysql_error(&mysql));
}

25.8.7.51. mysql_options4()

int mysql_options4(MYSQL *mysql, enum mysql_option option, const void *arg1, const void *arg2)

Описание

mysql_options4() подобен mysql_options(), но имеет дополнительный четвертый параметр, чтобы два значения можно было передать для опции, определенной во втором параметре.

Следующий список описывает разрешенные опции, их эффект и то, как использовать arg1 и arg2.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если Вы определяете неизвестную опцию.

Ошибки
Пример

Этот пример демонстрирует требования, которые определяют признаки соединения:

MYSQL mysql;

mysql_init(&mysql);
mysql_options(&mysql,MYSQL_OPT_CONNECT_ATTR_RESET, 0);
mysql_options4(&mysql,MYSQL_OPT_CONNECT_ATTR_ADD, "key1", "value1");
mysql_options4(&mysql,MYSQL_OPT_CONNECT_ATTR_ADD, "key2", "value2");
mysql_options4(&mysql,MYSQL_OPT_CONNECT_ATTR_ADD, "key3", "value3");
mysql_options(&mysql,MYSQL_OPT_CONNECT_ATTR_DELETE, "key1");
if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))
{
    fprintf(stderr, "Failed to connect to database: Error: %s\n",
  mysql_error(&mysql));
}

25.8.7.52. mysql_ping()

int mysql_ping(MYSQL *mysql)

Описание

Проверяет, работает ли соединение с сервером. Если соединение прервано и включено автоматическое пересоединение, будет предпринята попытка повторно соединиться. Если соединение прервано, но автоматическое пересоединение выключено, mysql_ping() вернет ошибку.

Автоматическое пересоединение по умолчанию выключено. Чтобы включить, вызовите mysql_options() с опцией MYSQL_OPT_RECONNECT.

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

Если mysql_ping() действительно вызывает повторно соединение, нет никакого явного признака этого. Чтобы определить, происходит ли повторно соединение, вызовите mysql_thread_id() , чтобы получить оригинальный идентификатор соединения перед запросом mysql_ping(), а потом вызовите mysql_thread_id() снова, чтобы увидеть, изменился ли идентификатор. Если повторное соединение происходит, некоторые его характеристики соединения будут сброшены.

Возвращаемые значения

Ноль, если соединение с сервером является активным. Отличное от нуля, если ошибка произошла. Возвращение отличное от нуля не указывает проблему с сервером: соединение может быть потеряно по другим причинам, таким как сетевые проблемы, например.

Ошибки

25.8.7.53. mysql_query()

int mysql_query(MYSQL *mysql, const char *stmt_str)

Описание

Выполняет запрос SQL, на который указывает законченная нулем строка stmt_str. Обычно строка должна состоять из единственного запроса SQL без заканчивающей точки с запятой (;) или \g. Если выполнение многих запросов было включено, строка может содержать несколько запросов, отделенных точками с запятой.

mysql_query() не может использоваться для запросов, которые содержат двоичные данные. Вы должны использовать mysql_real_query(). Двоичные данные могут содержать символ \0, который mysql_query() интерпретирует как конец строки.

Если Вы хотите знать, возвращает ли запрос набор результатов, Вы можете использовать mysql_field_count().

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

25.8.7.54. mysql_real_connect()

MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)

Описание

mysql_real_connect() пытается установить соединение с сервером MySQL на машине host. mysql_real_connect() должен завершиться успешно прежде, чем Вы сможете выполнить любые другие функции API, которые требуют допустимого дескриптора соединения MYSQL. Параметры определены следующим образом:

Если Ваша программа использует вызов CALL, чтобы выполнить хранимые процедуры, флаг CLIENT_MULTI_RESULTS должен быть включен. Это потому, что каждый CALL возвращает результат, чтобы указать на состояние запроса, в дополнение к любым наборам результатов, которые могли бы быть возвращены запросами, выполненными в пределах процедуры. Поскольку CALL может возвратить много наборов результатов, их надо обработать в цикле с помощью mysql_next_result().

CLIENT_MULTI_RESULTS может быть включен, когда Вы вызываете mysql_real_connect() явно, устанавливая флаг CLIENT_MULTI_RESULTS непосредственно, или неявно с помощью флага CLIENT_MULTI_STATEMENTS (который все равно включает CLIENT_MULTI_RESULTS). По умолчанию CLIENT_MULTI_RESULTS включен.

Если Вы включаете CLIENT_MULTI_STATEMENTS или CLIENT_MULTI_RESULTS, обработайте результат для каждого вызова mysql_query() или mysql_real_query() , используя цикличный вызов mysql_next_result() .

Для некоторых параметров возможно взять значение из файла опции, а не от явного значения в вызове mysql_real_connect() . Чтобы сделать это, вызовите mysql_options() с опцией MYSQL_READ_DEFAULT_FILE или MYSQL_READ_DEFAULT_GROUP до вызова mysql_real_connect() . Тогда в mysql_real_connect() укажите отсутствие значения для каждого параметра, который будет считан из файла опции:

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

Возвращаемые значения

Дескриптор соединения MYSQL*, если соединение было успешно, NULL, если соединение было неудачно. Для успешного соединения возвращаемое значение то же самое, что и значение первого параметра.

Ошибки
Пример
MYSQL mysql;

mysql_init(&mysql);
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name");
if (!mysql_real_connect(&mysql,"host","user","passwd","database",
    0,NULL,0)) {
   fprintf(stderr, "Failed to connect to database: Error: %s\n",
   mysql_error(&mysql));
}

При использовании mysql_options() MySQL читает секции [client] и [your_prog_name] в файле my.cnf, что гарантирует, что Ваша программа работает, даже если кто-то настроил MySQL некоторым нестандартным способом.

При подключении mysql_real_connect() устанавливает флаг reconnect (часть структуры MYSQL) в 1 в версиях более старого API чем 5.0.3, или в 0 в более новых версиях. Значение 1 этого флага указывает на это, если запрос не может быть выполнен из-за потерянного соединения, надо попытаться повторно соединиться с сервером перед отказом. Вы можете использовать опцию MYSQL_OPT_RECONNECT в mysql_options(), чтобы управлять поведением пересоединения.

25.8.7.55. mysql_real_escape_string()

unsigned long mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned long length)

Описание

Эта функция создает правильную строку для использования в SQL-запросе. mysql_real_escape_string() производит ошибку CR_INSECURE_API_ERR, если включен режим SQL NO_BACKSLASH_ESCAPES. В этом случае функция не может выйти из символов кавычки, кроме как удваивая их, а чтобы сделать это должным образом, она должна знать больше информации о контексте, заключенном в кавычки, чем ей доступно. Вместо этого используйте mysql_real_escape_string_quote(), которая берет дополнительный параметр для определения контекста, заключенного в кавычки.

Параметр mysql должен быть допустимым, открытым соединением, потому что символьный вывод зависит от набора символов, используемом сервером.

Строка в from будет закодирована, чтобы произвести строку SQL, принимая во внимание текущий набор символов соединения. Результат помещен в параметр to, сопровождаемый заканчивающим нулевым байтом.

Закодированные символы \, ', ", NUL (ASCII 0), \n, \r и Control+Z. Строго говоря, MySQL требует только, чтобы наклонная черта влево и символ кавычки, используемые для цитирования строки в запросе, были экранированы. mysql_real_escape_string() заключает другие символы в кавычки, чтобы их было легче читать в файлах системного журнала. Для сравнения, см. правила заключения в кавычки для строк литералов и SQL-функции QUOTE() в разделе 10.1.1. Строковые литералы и раздел 13.5. Строковые функции.

Строка, указанная в from должна быть length байтов в длину. Вы должны выделить буфер для to по крайней мере length*2+1 байт. В худшем случае каждый символ, возможно, должен быть закодирован как два байта и должно быть место для заканчивающего нулевого байта. Когда mysql_real_escape_string() завершится, содержанием to будет строка, законченная нулем. Возвращаемое значение длина закодированной строки, не включая заканчивающий нулевой байт.

Если Вы должны изменить набор символов соединения, используйте функцию mysql_set_character_set() вместо того, чтобы выполнить SET NAMES (или SET CHARACTER SET ). mysql_set_character_set() работает подобно SET NAMES, но затрагивает также и набор символов, используемый mysql_real_escape_string().

Пример

Следующий пример вставляет две экранированных строки в запрос INSERT, каждая берется в символы одинарной кавычки:

char query[1000],*end;

end = my_stpcpy(query,"INSERT INTO test_table VALUES('");
end += mysql_real_escape_string(&mysql,end,"What is this",12);
end = my_stpcpy(end,"','");
end += mysql_real_escape_string(&mysql,end,"binary data: \0\r\n",16);
end = my_stpcpy(end,"')");
if (mysql_real_query(&mysql,query,(unsigned int) (end - query))) {
   fprintf(stderr, "Failed to insert row, Error: %s\n",
           mysql_error(&mysql));
}

Функция my_stpcpy(), используемая в примере, включена в библиотеку libmysqlclient и работает как strcpy(), но возвращает указатель на заканчивающий нуль первого параметра.

Возвращаемые значения

Длина закодированной строки, которая помещена в параметр to, не включая заканчивающий нулевой байт, или -1, если ошибка происходит.

Поскольку mysql_real_escape_string() возвращает значение без знака, Вы можете проверить на-1, сравнивая возвращаемое значение с (unsigned long)-1.

Ошибки

25.8.7.56. mysql_real_escape_string_quote()

unsigned long mysql_real_escape_string_quote(MYSQL *mysql, char *to, const char *from, unsigned long length, char quote)

Описание

Эта функция создает правильную строку для использования в SQL-запросе в целом аналогично mysql_real_escape_string(). Однако, есть отличия.

Если включен режим SQL ANSI_QUOTES, mysql_real_escape_string_quote() не может использоваться, чтобы экранировать символы двойной кавычки для использования в идентификаторах в двойных кавычках. Функция не может сказать, позволено ли режиму определить надлежащий символ экранировки.

Строка, указанная в from должна быть length байтов в длину. Вы должны выделить буфер для to по крайней мере length*2+1 байт. В худшем случае каждый символ, возможно, должен быть закодирован как два байта и должно быть место для заканчивающего нулевого байта. Когда mysql_real_escape_string() завершится, содержанием to будет строка, законченная нулем. Возвращаемое значение длина закодированной строки, не включая заканчивающий нулевой байт.

Параметр quote указывает на контекст, в который должна быть помещена экранированная строка. Предположим, что Вы намереваетесь экранировать параметр from и вставить строку (определяемую здесь как str) в один из следующих запросов:

1) SELECT * FROM table WHERE name = 'str'
2) SELECT * FROM table WHERE name = "str"
3) SELECT * FROM `str` WHERE id = 103

Чтобы выполнить экранировку должным образом для каждого запроса, выполните mysql_real_escape_string_quote() следующим образом, где заключительный параметр указывает на контекст заключения в кавычки:

1) len = mysql_real_escape_string_quote(&mysql,to,from,from_len,'\'');
2) len = mysql_real_escape_string_quote(&mysql,to,from,from_len,'"');
3) len = mysql_real_escape_string_quote(&mysql,to,from,from_len,'`');

Если Вы должны изменить набор символов соединения, используйте функцию mysql_set_character_set() вместо того, чтобы выполнить команду SET NAMES (или SET CHARACTER SET ). mysql_set_character_set() работает похоже на SET NAMES, но также затрагивает и набор символов, используемый mysql_real_escape_string_quote(), который SET NAMES не трогает.

Пример

Следующий пример вставляет две строки в запрос INSERT, каждая в обрамлении символов одинарной кавычки:

char query[1000],*end;

end = my_stpcpy(query,"INSERT INTO test_table VALUES('");
end += mysql_real_escape_string_quote(&mysql,end,"What is this",12,'\'');
end = my_stpcpy(end,"','");
end += mysql_real_escape_string_quote(&mysql,end,"binary data: \0\r\n",
                                      16,'\'');
end = my_stpcpy(end,"')");
if (mysql_real_query(&mysql,query,(unsigned int) (end - query))) {
   fprintf(stderr, "Failed to insert row, Error: %s\n",
           mysql_error(&mysql));
}
Возвращаемые значения

Длина закодированной строки, которая помещена в параметр to, не включая заканчивающий нулевой байт.

Ошибки

Нет.

25.8.7.57. mysql_real_query()

int mysql_real_query(MYSQL *mysql, const char *stmt_str, unsigned long length)

Описание

Выполняет SQL-запрос, указанный в строке stmt_str length байтов длиной. Обычно строка должна состоять из единственного запроса SQL без заканчивающей точки с запятой (;) или \g. Если выполнение нескольких запросов было включено, строка может содержать несколько запросов, отделенных точками с запятой.

mysql_query() не может использоваться для запросов, которые содержат двоичные данные, Вы должны использовать вместо этого mysql_real_query() . Двоичные данные могут содержать символ \0, который mysql_query() интерпретирует как конец строки. Кроме того, mysql_real_query() быстрее, чем mysql_query(), поскольку не вызывает strlen().

Если Вы хотите знать, возвращает ли запрос набор результатов, Вы можете использовать mysql_field_count(), чтобы проверить это.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

25.8.7.58. mysql_refresh()

int mysql_refresh(MYSQL *mysql, unsigned int options)

Описание

mysql_refresh() устарела и будет удалена в будущих версиях MySQL. Вместо нее используйте mysql_query(), чтобы выполнить команду FLUSH .

Эта функция сбрасывает таблицы или кэши, или информацию о сервере репликаций. Соединенный пользователь должен иметь привилегию RELOAD.

Параметр options является битовой маской, составленной из любой комбинации следующих значений. Много значений могут быть объединены через OR вместе, чтобы выполнить много операций за один вызов.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

25.8.7.59. mysql_reload()

int mysql_reload(MYSQL *mysql)

Описание

Просит сервер MySQL перезагрузить таблицы привилегий. Соединенный пользователь должен иметь привилегию RELOAD.

Эта функций устарела. Вместо нее следует использовать mysql_query() для выполнения запроса SQL FLUSH PRIVILEGES.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

25.8.7.60. mysql_reset_connection()

int mysql_reset_connection(MYSQL *mysql)

Описание

Сбрасывает соединение, чтобы очистить статус сеанса.

mysql_reset_connection() имеет эффекты, подобные mysql_change_user() или автоматическому переподключению за исключением того, что соединение не закрыто и вновь открыто, а переаутентификация не сделана.

Связанное с соединением состояние меняется следующим образом:

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

25.8.7.61. mysql_rollback()

my_bool mysql_rollback(MYSQL *mysql)

Описание

Откатывает текущую транзакцию. Действие этой функции зависит от значения системной переменной completion_type. В частности, если значение completion_type RELEASE (или 2), сервер выполняет отмену после завершения транзакции и закрывает соединение клиента. Вызовите mysql_close() из из программы клиента, чтобы закрыть соединение со стороны клиента.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

Нет.

25.8.7.62. mysql_row_seek()

MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)

Описание

Устанавливает курсор строки в произвольную строку в наборе результатов запроса. Значение offset смещение строки, как правило значение из mysql_row_tell() или mysql_row_seek(). Это значение не номер строки, чтобы перейти на строку в пределах набора результатов по номеру, используйте mysql_data_seek() .

Эта функция требует, чтобы структура набора результатов содержала весь результат запроса, таким образом, mysql_row_seek() может использоваться только вместе с mysql_store_result() , но не с mysql_use_result() .

Возвращаемые значения

Предыдущяя позиция курсора строки. Это значение можно передать последующему вызову mysql_row_seek() .

Ошибки

Нет.

25.8.7.63. mysql_row_tell()

MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)

Описание

Возвращает текущую позицию курсора строки для последнего вызова mysql_fetch_row() . Это значение может использоваться в качестве параметра mysql_row_seek() .

Используйте mysql_row_tell() только после mysql_store_result() , но не после mysql_use_result() .

Возвращаемые значения

Текущее смещение курсора строки.

Ошибки

Нет.

25.8.7.64. mysql_select_db()

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

Описание

Назначает базу данных, определенную db, базой данных по умолчанию для соединения, определенного mysql. В последующих запросах эта база данных будет значением по умолчанию для табличных ссылок, которые не включают явного спецификатора базы данных.

mysql_select_db() терпит неудачу, если соединенный пользователь не имеет права использовать эту базу данных.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

25.8.7.65. mysql_session_track_get_first()

int mysql_session_track_get_first(MYSQL *mysql, enum enum_session_state_type type, const char **data, size_t *length)

Описание

Эта функция приносит первую информацию об изменении состояния сеанса, полученную от сервера.

Чтобы управлять уведомлением об изменениях состояния сессии, используйте системные переменные session_track_state_change, session_track_schema, session_track_system_variables и session_track_gtids.

Функциональные параметры используются следующим образом. Эти описания также относятся к mysql_session_track_get_first(), которая берет те же самые параметры.

После успешного вызова, интерпретируйте значения data и length согласно type следующим образом:

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

Нет.

Пример

Следующий пример показывает, как вызвать mysql_session_track_get_first() и mysql_session_track_get_next(), чтобы получить и вывести на экран всю доступную информацию об изменении состояния сессии после успешного выполнения строки запроса SQL stmt_str.

printf("Execute: %s\n", stmt_str);
if (mysql_query(mysql, stmt_str) != 0) {
   fprintf(stderr, "Error %u: %s\n", mysql_errno(mysql), mysql_error(mysql));
   return;
}
MYSQL_RES *result = mysql_store_result(mysql);
if (result) /* there is a result set to fetch */ {
   /* ... process rows here ... */
   printf("Number of rows returned: %lu\n",
          (unsigned long) mysql_num_rows(result));
   mysql_free_result(result);
}
else  /* there is no result set */
{
  if (mysql_field_count(mysql) == 0) {
     printf("Number of rows affected: %lu\n",
            (unsigned long) mysql_affected_rows(mysql));
  }
  else /* an error occurred */
  {
    fprintf(stderr, "Error %u: %s\n", mysql_errno(mysql), mysql_error(mysql));
  }
}
/* extract any available session state-change information */
enum enum_session_state_type type;
for (type = SESSION_TRACK_BEGIN; type <= SESSION_TRACK_END; type++) {
  const char *data;
  size_t length;

  if (mysql_session_track_get_first(mysql, type, &data,
     &length) == 0) {
     printf("Type=%d:\n", type);
     printf("mysql_session_track_get_first() returns: %*.*s\n",
            (int) length, (int) length, data);
     /* check for more data */
     while (mysql_session_track_get_next(mysql, type, &data,
            &length) == 0) {
       printf("mysql_session_track_get_next() returns: %*.*s\n",
              (int) length, (int) length, data);
     }
  }
}

25.8.7.66. mysql_session_track_get_next()

int mysql_session_track_get_next(MYSQL *mysql, enum enum_session_state_type type, const char **data, size_t *length)

Описание

Эта функция приносит информацию об изменении состояния сеанса, полученную от сервера после mysql_session_track_get_first().

После успешного вызова mysql_session_track_get_first() вызывайте mysql_session_track_get_next() неоднократно, пока это не вернет отличное от нуля значение, чтобы указать, что больше информации не доступно. Последовательность запроса для mysql_session_track_get_next() подобна mysql_session_track_get_first().

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

Нет.

25.8.7.67. mysql_set_character_set()

int mysql_set_character_set(MYSQL *mysql, const char *csname)

Описание

Эта функция используется, чтобы установить набор символов по умолчанию для текущего соединения. Строка csname определяет допустимое имя набора символов. Сопоставление соединения становится сопоставлением по умолчанию набора символов. Эта функция работает как SET NAMES, но также меняет значение mysql->charset и таким образом затрагивает набор символов, используемый mysql_real_escape_string().

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Пример
MYSQL mysql;

mysql_init(&mysql);
if (!mysql_real_connect(&mysql,"host","user","passwd","database",
    0,NULL,0)) {
   fprintf(stderr, "Failed to connect to database: Error: %s\n",
   mysql_error(&mysql));
}
if (!mysql_set_character_set(&mysql, "utf8")) {
   printf("New client character set: %s\n",
          mysql_character_set_name(&mysql));
}

25.8.7.68. mysql_set_local_infile_default()

void mysql_set_local_infile_default(MYSQL *mysql);

Описание

Устанавливает обработчик LOAD DATA LOCAL INFILE в значение по умолчанию, используемое внутренне библиотекой клиента C. Библиотека вызывает эту функцию автоматически, если mysql_set_local_infile_handler() не был вызван или не поставляет допустимые функции для каждого из вызовов.

Возвращаемые значения

Нет.

Ошибки

Нет.

25.8.7.69. mysql_set_local_infile_handler()

void mysql_set_local_infile_handler(MYSQL *mysql, int (*local_infile_init)(void **, const char *, void *), int (*local_infile_read)(void *, char *, unsigned int), void (*local_infile_end)(void *), int (*local_infile_error)(void *, char*, unsigned int), void *userdata);

Описание

Эта функция устанавливает обработчики, которые будут использоваться во время выполнения LOAD DATA LOCAL INFILE. Это позволяет приложениям осуществить контроль над местным (сторона клиента) чтением файла с данными. Параметры: обработчик соединения, ряд указателей на функции обратного вызова и указатель на область данных, которую могут использовать, чтобы поделиться информацией.

Чтобы использовать mysql_set_local_infile_handler(), Вы должны написать следующие функции обратного вызова:

int local_infile_init(void **ptr, const char *filename, void *userdata);

Функция инициализации. Это вызывают однажды, чтобы сделать любую необходимую настройку, открыть файл с данными, выделить структуры данных и т.д. Первый аргумент void** указатель на указатель. Вы можете установить указатель (то есть, *ptr) к значению, которое передадут каждому из других обработчиков (как void*). Обработчики могут использовать этот указатель на значение, чтобы поддержать информацию статуса. Параметр userdata то же самое значение, которое передают mysql_set_local_infile_handler().

Заставьте функцию инициализации возвратить ноль для успеха, отличное от нуля значение для ошибки.

int local_infile_read(void *ptr, char *buf, unsigned int buf_len);

Читающая данные функция. Это вызывают неоднократно, чтобы считать файл с данными. buf указывает на буфер, где данные о чтении хранятся, а buf_len задает максимальное количество байтов, которые обработчик может считать и сохранить в буфере. Это может считать меньше байтов, но не должно читать больше.

Возвращаемое значение: число реально прочитанных байтов или ноль, когда больше данных не могло быть считано (это указывает на EOF). Верните значение меньше, чем ноль, если ошибка происходит.

void local_infile_end(void *ptr)

Функция завершения. Это вызывают однажды после того, как local_infile_read() вернет 0 (EOF) или ошибку. В пределах этой функции, освободите любую память, выделенную local_infile_init(), и выполните любую другую необходимую уборку. Это вызвано, даже если функция инициализации возвращает ошибку.

int local_infile_error(void *ptr, char *error_msg,
                       unsigned int error_msg_len);

Функция обработки ошибок. Это вызывают, чтобы вернуть пользователю текстовое сообщение об ошибке в случае, если любая из Ваших других функций возвращает ошибку. error_msg указывает на буфер, в который сообщение записано, а error_msg_len является длиной буфера. Пишите сообщение как законченную нулем строку, самое большее error_msg_len-1 байт длиной.

Возвращаемое значение код ошибки. Как правило, обработчики хранят сообщение об ошибке в структуре данных, которую указывают в ptr так, чтобы local_infile_error() мог скопировать сообщение оттуда в error_msg.

После вызова mysql_set_local_infile_handler() в Вашем коде C и обработке указателей на ваши обработчики, Вы можете вызвать оператор LOAD DATA LOCAL INFILE (например, через mysql_query()). Библиотека клиента автоматически вызывает Ваши обработчики. Имя файла, определенное в LOAD DATA LOCAL INFILE, будет передано как второй параметр в local_infile_init().

Возвращаемые значения

Нет.

Ошибки

Нет.

25.8.7.70. mysql_set_server_option()

int mysql_set_server_option(MYSQL *mysql, enum enum_mysql_set_option option)

Описание

Включает или отключает опцию для соединения. option может иметь одно из следующих значений.

ОпцияОписание
MYSQL_OPTION_MULTI_STATEMENTS_ON Включить поддержку нескольких запросов сразу.
MYSQL_OPTION_MULTI_STATEMENTS_OFF Выключить поддержку нескольких запросов сразу.

Если Вы включите поддержку нескольких запросов сразу, Вы должны получить результаты вызовов mysql_query() или mysql_real_query() применяя циклический вызов mysql_next_result() , чтобы определить, есть ли еще результаты.

Включение поддержки нескольких запросов сразу с помощью MYSQL_OPTION_MULTI_STATEMENTS_ON имеет не вполне тот же самый эффект, как включение с помощью флага CLIENT_MULTI_STATEMENTS в mysql_real_connect() : CLIENT_MULTI_STATEMENTS также включает CLIENT_MULTI_RESULTS. Если Вы используете SQL-запрос CALL в Ваших программах, поддержка многоих результатов должна быть включена, это означает, что MYSQL_OPTION_MULTI_STATEMENTS_ON отдельно недостаточно, чтобы разрешить использование CALL.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

25.8.7.71. mysql_sqlstate()

const char *mysql_sqlstate(MYSQL *mysql)

Описание

Возвращает законченную нулем строку, содержащую код ошибки SQLSTATE для последнего выполненного SQL-запроса. Код ошибки состоит из пяти символов. '00000' означает отсутствие ошибки. Значения определены ANSI SQL и ODBC.

Значения SQLSTATE, возвращенные mysql_sqlstate() отличаются от MySQL-специфичных кодов ошибки, возвращенных mysql_errno(). Например, программа клиента mysql выводит на экран ошибки, используя следующий формат, где 1146 значение из mysql_errno(), а '42S02' значение из mysql_sqlstate() :

shell> SELECT * FROM no_such_table;
ERROR 1146 (42S02): Table 'test.no_such_table' doesn't exist

Не все коды ошибок MySQL отображены на коды ошибки SQLSTATE. Значение 'HY000' (general error) используется для неотображенных кодов ошибки.

Если Вы вызываете mysql_sqlstate() после сбоя mysql_real_connect() , mysql_sqlstate() не может возвратить полезное значение. Например, это происходит, если сервер свалился, и соединение закрыто без какого-либо значения SQLSTATE, посылаемого клиенту.

Возвращаемые значения

Законченная нулем строка символов, содержащая код ошибки SQLSTATE.

25.8.7.72. mysql_ssl_set()

my_bool mysql_ssl_set(MYSQL *mysql, const char *key, const char *cert, const char *ca, const char *capath, const char *cipher)

Описание

mysql_ssl_set() используется для того, чтобы создавать безопасные соединения, используя SSL. Это нужно вызвать прежде, чем mysql_real_connect() . mysql_ssl_set() ничего не делает, если поддержка SSL не включена в библиотеке клиента.

mysql это дескриптор соединения, возвращенный из mysql_init(). Другие параметры определены следующим образом:

Любые неиспользованные параметры SSL могут быть заданы как NULL.

Возвращаемые значения

Эта функция всегда возвращает 0. Если установка SSL является неправильной, mysql_real_connect() возвращает ошибку, когда Вы пытаетесь соединиться.

25.8.7.73. mysql_stat()

const char *mysql_stat(MYSQL *mysql)

Описание

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

Возвращаемые значения

Строка символов, описывающая состояние сервера. NULL, если ошибка произошла.

Ошибки

25.8.7.74. mysql_store_result()

MYSQL_RES *mysql_store_result(MYSQL *mysql)

Описание

После вызова mysql_query() или mysql_real_query() Вы должны вызвать mysql_store_result() или mysql_use_result() для каждого запроса, который успешно производит набор результатов (SELECT, SHOW, DESCRIBE, EXPLAIN, CHECK TABLE и т.п.). Вы должны также вызвать mysql_free_result() после того, как Вы завершили работу с набором результатов.

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

Если Вы включаете поддержку многих запросов, Вы должны получить результаты вызовов mysql_query() или mysql_real_query(), применяя в цикле mysql_next_result() , чтобы определить, есть ли еще результаты.

Если Вы хотите знать, должен ли запрос вообще вернуть набор результатов, Вы можете использовать mysql_field_count().

mysql_store_result() читает весь результат запроса клиенту, выделяет структуру MYSQL_RES и помещает результат в эту структуру.

mysql_store_result() возвращает нулевой указатель, если запрос не возвращал набор результатов (например, если это был INSERT).

mysql_store_result() также возвращает нулевой указатель, если набор результатов не может быть прочитан. Вы можете проверить, произошла ли ошибка, вызовом mysql_error(). Здесь надо проверить, вернет ли этот вызов непустую строку. mysql_errno() вернет значение, отличное от нуля, или mysql_field_count() вернет 0.

Пустой набор результатов возвращен, если нет никаких возвращенных строк. Пустой набор результатов отличается от нулевого указателя как возвращаемое значение.

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

Вы можете вызвать mysql_fetch_row(), чтобы получить строки из набора результатов, или mysql_row_seek() и mysql_row_tell(), чтобы получить или установить текущую позицию строки в пределах набора результатов.

Возвращаемые значения

Структура MYSQL_RES с результатами. NULL (0), если ошибка произошла.

Ошибки

mysql_store_result() сбрасывает mysql_error() и mysql_errno(), если все хорошо.

25.8.7.75. mysql_thread_id()

unsigned long mysql_thread_id(MYSQL *mysql)

Описание

Возвращает ID потока текущего соединения. Это значение может использоваться в качестве параметра mysql_kill(), чтобы уничтожить поток.

Если соединение потеряно, и Вы повторно соединяетесь с mysql_ping(), ID меняется. Это означает, что Вы не должны получить ID потока и сохранить его для использования позже. Вы должны получить его, когда это надо.

Эта функция не работает правильно, если ID становятся больше, чем 32 бита, что может произойти на некоторых системах. Чтобы избежать проблем с mysql_thread_id() , не используйте это. Чтобы получить ID, выполните запрос SELECT CONNECTION_ID() и получите результат.

Возвращаемые значения

ID потока для текущего соединения.

Ошибки

Нет.

25.8.7.76. mysql_use_result()

MYSQL_RES *mysql_use_result(MYSQL *mysql)

Описание

После вызова mysql_query() или mysql_real_query() Вы должны вызвать mysql_store_result() или mysql_use_result() для каждого запроса, который успешно производит набор результатов (SELECT, SHOW, DESCRIBE, EXPLAIN, CHECK TABLE и т.п.). Вы должны также вызвать mysql_free_result() после завершения работы с набором результатов.

mysql_use_result() начинает извлечение набора результатов, но фактически не загружает набор результатов в клиента как mysql_store_result() . Вместо этого каждая строка должна быть получена индивидуально, делая запросы mysql_fetch_row(). Это читает результат запроса непосредственно с сервера, не храня его во временной таблице или местном буфере, который несколько быстрее, и использует намного меньше памяти, чем mysql_store_result() . Клиент выделяет память только для текущей строки и коммуникационного буфера, который может расти до max_allowed_packet байт.

С другой стороны, Вы не должны использовать mysql_use_result() для того, чтобы заблокировать чтения, если Вы делаете большую обработку для каждой строки на стороне клиента, или если вывод посылаете на экран, на котором пользователь может нажать ^S (stop scroll). Это связывает сервер и препятствует тому, чтобы другие потоки обновили любые таблицы, из которых читаются данные.

Используя mysql_use_result(), Вы должны выполнять mysql_fetch_row() до получения значения NULL, иначе непрочитанные строки будут возвращены как часть набора результатов для Вашего следующего запроса. C API дает ошибку Commands out of sync; you can't run this command now , если Вы забываете делать это! Ну и на том спасибо, еще бы молча вернул не то...

Вы не можете использовать mysql_data_seek() , mysql_row_seek() , mysql_row_tell() , mysql_num_rows() или mysql_affected_rows() с результатом, возвращенным из mysql_use_result() и при этом Вы не можете запустить другие запросы, пока mysql_use_result() не закончится. Однако, после того, как Вы получили все строки, mysql_num_rows() точно возвращает число строк.

Вы должны вызвать mysql_free_result() как только закончите с набором результатов. Используя libmysqld, выгода по памяти по существу теряется, потому что использование памяти не увеличивается с каждой строкой, полученной от mysql_free_result() .

Возвращаемые значения

Структура результата MYSQL_RES. NULL, если ошибка произошла.

Ошибки

mysql_use_result() сбрасывает mysql_error() и mysql_errno(), если все нормально.

25.8.7.77. mysql_warning_count()

unsigned int mysql_warning_count(MYSQL *mysql)

Описание

Возвращает число ошибок, предупреждений и примечаний во время выполнения предыдущего SQL-запроса.

Возвращаемые значения

Количество сгенерированных предупреждений.

Ошибки

Нет.

25.8.8. Подготовленные запросы в C API

Протокол клиент-сервер MySQL предусматривает использование готовых запросов. Эта способность использует структуру данных обработчика MYSQL_STMT, возвращенную функцией инициализации mysql_stmt_init() . Готовое выполнение эффективный способ выполнить запрос не раз. Запрос сначала разобран, чтобы подготовить его к выполнению. Потом он будет выполнен один или более раз в более позднее время, используя дескриптор запроса, возвращенный функцией инициализации.

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

Готовые запросы не могли бы обеспечить исполнительное ускорение некоторых ситуаций. Для лучших результатов проверьте свое приложение с готовыми и с не готовыми запросами. Ввыберите, что приводит к лучшей работе.

Другое преимущество готовых запросов состоит в том, что это использует протокол двоичной синхронной передачи данных, который делает передачу данных между клиентом и сервером более эффективной.

За списком команд SQL, которые могут использоваться в качестве подготовленных, обратитесь к разделу 14.5. Синтаксис подготовленных SQL-запросов.

Метаданные, измененные для таблицы или обзора, связанных с готовым запросом, будут обнаружены и вызывают автоматическую переподготовку запроса. Для получения дополнительной информации, см. раздел 9.10.4. Кэширование подготовленных запросов и сохраненных процедур.

25.8.9. Структуры данных подготовленных запросов C API

Готовые запросы используют несколько структур данных:

Следующее обсуждение описывает готовые типы данных подробно. Для примеров, которые показывают, как использовать их, см. раздел 25.8.11.10. mysql_stmt_execute() и раздел 25.8.11.11. mysql_stmt_fetch().

25.8.9.1. Коды типа подготовленных запросов C API

Член buffer_type структуры MYSQL_BIND указывает тип данных переменной языка C, связанной с параметром запроса или столбцом набора результатов. Для ввода buffer_type указывает на тип переменной, содержащей значение, которое будет послано серверу. Для вывода это указывает на тип переменной, в которую должно быть сохранено значение, полученное от сервера.

Следующая таблица показывает допустимые значения для члена buffer_type структуры MYSQL_BIND для входных значений, посланных серверу. Таблица показывает типы переменных C, которые Вы можете использовать, соответствующие коды типа и типы данных SQL, для которых поставляемое значение может использоваться без преобразования. Выберите значение buffer_type согласно типу данных переменной языка C, которую Вы связываете. Для типов целого числа Вы должны также установить член is_unsigned, чтобы указать со знаком число или без него.

Тип входной переменной на C Значение buffer_type SQL-тип целевого значения
signed char MYSQL_TYPE_TINY TINYINT
short int MYSQL_TYPE_SHORT SMALLINT
intMYSQL_TYPE_LONG INT
long long int MYSQL_TYPE_LONGLONG BIGINT
floatMYSQL_TYPE_FLOAT FLOAT
doubleMYSQL_TYPE_DOUBLE DOUBLE
MYSQL_TIMEMYSQL_TYPE_TIME TIME
MYSQL_TIMEMYSQL_TYPE_DATE DATE
MYSQL_TIMEMYSQL_TYPE_DATETIME DATETIME
MYSQL_TIME MYSQL_TYPE_TIMESTAMP TIMESTAMP
char[]MYSQL_TYPE_STRING TEXT, CHAR, VARCHAR
char[]MYSQL_TYPE_BLOB BLOB, BINARY, VARBINARY
MYSQL_TYPE_NULL NULL

Используйте MYSQL_TYPE_NULL как обозначено в описании для is_null в разделе 25.8.9. Структуры данных подготовленных запросов C API.

Для входных строковых данных, используйте MYSQL_TYPE_STRING или MYSQL_TYPE_BLOB в зависимости от того, является ли значение символьной или двоичной строкой:

Следующая таблица показывает допустимые значения для buffer_type структуры MYSQL_BIND для выходных значений, полученных от сервера. Таблица показывает типы SQL полученных значений, соответствующие коды типа, что такие значения имеют в метаданных о наборе результатов и рекомендуемые типы данных языка C, чтобы связать со структурой MYSQL_BIND, чтобы получить значения SQL без преобразования. Выберите значение buffer_type согласно типу данных переменной языка C, которую Вы связываете. Для типов целого числа Вы должны также установить член is_unsigned, чтобы указать наличие признака знака числа.

SQL-тип полученного значения Значение buffer_type Тип выходной переменной C
TINYINTMYSQL_TYPE_TINY signed char
SMALLINT MYSQL_TYPE_SHORT short int
MEDIUMINTMYSQL_TYPE_INT24 int
INT MYSQL_TYPE_LONGint
BIGINT MYSQL_TYPE_LONGLONG long long int
FLOATMYSQL_TYPE_FLOAT float
DOUBLEMYSQL_TYPE_DOUBLE double
DECIMAL MYSQL_TYPE_NEWDECIMAL char[]
YEAR MYSQL_TYPE_SHORTshort int
TIME MYSQL_TYPE_TIMEMYSQL_TIME
DATE MYSQL_TYPE_DATEMYSQL_TIME
DATETIME MYSQL_TYPE_DATETIME MYSQL_TIME
TIMESTAMP MYSQL_TYPE_TIMESTAMP MYSQL_TIME
CHAR, BINARY MYSQL_TYPE_STRINGchar[]
VARCHAR, VARBINARY MYSQL_TYPE_VAR_STRINGchar[]
TINYBLOB, TINYTEXT MYSQL_TYPE_TINY_BLOBchar[]
BLOB, TEXT MYSQL_TYPE_BLOBchar[]
MEDIUMBLOB , MEDIUMTEXT MYSQL_TYPE_MEDIUM_BLOBchar[]
LONGBLOB, LONGTEXT MYSQL_TYPE_LONG_BLOBchar[]
BIT MYSQL_TYPE_BITchar[]

25.8.9.2. Преобразования типа готовых запросов в C API

Готовые запросы передают данные между клиентом и сервером, используя переменные языка C на стороне клиента, которые соответствуют значениям SQL на стороне сервера. Если есть несоответствие между типом C на стороне клиента и соответствующим типом значения SQL на стороне сервера, MySQL выполняет неявные преобразования типа в обоих направлениях.

MySQL знает код типа для значения SQL на стороне сервера. Значение buffer_type в структуре MYSQL_BIND указывает на код типа переменной C, которая содержит значение на стороне клиента. Два кода вместе говорят MySQL, какое преобразование должно быть выполнено, если надо. Вот некоторые примеры:

Перед обязательными переменными структуры MYSQL_BIND, которые должны использоваться для того, чтобы принести значения столбцов, Вы можете проверить коды типа на каждый столбец набора результатов. Это может быть желательно, если Вы хотите определить, какие типы переменных были бы лучше, чтобы избежать преобразований типа. Чтобы получить коды типа, вызовите mysql_stmt_result_metadata() после выполнения готового запроса с mysql_stmt_execute() . Метаданные обеспечивают доступ к кодам типа для набора результатов как описано в разделе 25.8.11.23. mysql_stmt_result_metadata() и разделе 25.8.5. Структуры данных C API.

Чтобы определить, содержат ли выведенные строковые значения в наборе результатов с сервера двоичные данные проверьте, равно ли значение charsetnr метаданных о наборе результатов 63. Если это так, набор символов binary, который указывает на двоичные данные. Это позволяет Вам отличить тип BINARY от CHAR, VARBINARY от VARCHAR и BLOB от TEXT.

Если Вы устанавливаете член max_length метаструктуры данных MYSQL_FIELD столбца (вызовом mysql_stmt_attr_set()), знайте что значения max_length для набора результатов указывают на размер самого длинного строкового, а не двоичного представления значений результата. Таким образом, max_length не обязательно соответствует размеру буфера, который должен был принести значения с протоколом двоичной синхронной передачи данных, используемым для готовых запросов. Выберите размер буферов согласно типам переменных, в которые Вы сохраняете значения. Например, столбец TINYINT, содержащий значение -128, может иметь значение max_length 4. Но двойное представление любого TINYINT требует только 1 байт для хранения, таким образом, Вы можете задействовать переменную signed char, в которой можно сохранить значение и установить is_unsigned, чтобы указать, что значения со знаком.

Метаданные измененные для таблиц или обзоров, упомянутых готовыми запросами, обнаружены и вызывают автоматическую переподготовку запроса, когда он затем выполнен.

25.8.10. Обзор функций C API для подготовленных запросов

Функции, доступные для готовой обработки запроса обобщены здесь и описаны более подробно в позже.

Функция Описание
mysql_stmt_affected_rows() Возвращает число строк измененных, удаленных или вставленных запросом UPDATE, DELETE или INSERT.
mysql_stmt_attr_get() Получает значение признака для готового запроса.
mysql_stmt_attr_set() Задает значение признака для готового запроса.
mysql_stmt_bind_param() Связывает буфера данных приложения с маркерами параметра в готовом запросе SQL.
mysql_stmt_bind_result() Связывает буфера данных приложения со столбцами в наборе результатов.
mysql_stmt_close() Освобождает используемую память.
mysql_stmt_data_seek() Переходит на произвольный номер строки в наборе результатов.
mysql_stmt_errno() Возвращает код ошибки для последнего выполнения запроса.
mysql_stmt_error() Возвращает сообщение об ошибке для последнего выполнения запроса.
mysql_stmt_execute() Выполняет готовый запрос.
mysql_stmt_fetch() Приносит следующую строку данных из набора результатов и возвращает данные для всех связанных столбцов.
mysql_stmt_fetch_column() Получает данные для одного столбца текущей строки набора результатов.
mysql_stmt_field_count() Возвращает число столбцов результата для нового запроса.
mysql_stmt_free_result() Освобождает ресурсы, выделенные дескриптору запроса.
mysql_stmt_init() Выделяет память для структуры MYSQL_STMT и инициализирует ее.
mysql_stmt_insert_id() Возвращает ID, произведенное для столбца AUTO_INCREMENT готовым запросом.
mysql_stmt_next_result() Возвращает/начинает следующий результат, если результатов несколько.
mysql_stmt_num_rows() Возвращает количество строк из буферизованного набора результатов запроса.
mysql_stmt_param_count() Возвращает число параметров в готовом запросе.
mysql_stmt_param_metadata() Эта функция ничего не делает.
mysql_stmt_prepare() Готовит строку запроса SQL к выполнению.
mysql_stmt_reset() Сбрасывает буферы запроса в сервере.
mysql_stmt_result_metadata() Возвращает подготовленные метаданные о запросе в форме набора результатов.
mysql_stmt_row_seek() Переходит на смещение строки в наборе результатов, используя значение возвращенное из mysql_stmt_row_tell().
mysql_stmt_row_tell() Возвращает позицию курсора строки запроса.
mysql_stmt_send_long_data() Посылает длинные данные в кусках серверу.
mysql_stmt_sqlstate() Возвращает код ошибки SQLSTATE для последнего выполнения запроса.
mysql_stmt_store_result() Получает полный набор результатов.

Вызовите mysql_stmt_init() , чтобы создать дескриптор заявления, затем mysql_stmt_prepare() , чтобы подготовить строку, снабдите ее данными для параметров через mysql_stmt_bind_param() и выполните с помощью mysql_stmt_execute() . Вы можете повторить mysql_stmt_execute() изменяя параметры в соответствующих буферах, поставляемых через mysql_stmt_bind_param().

Вы можете послать текст или двоичные данные в кусках серверу, используя mysql_stmt_send_long_data().

Если запрос SELECT или любой другой, который производит набор результатов, mysql_stmt_prepare() также возвращает информацию о метаданных о наборе результатов в форме набора результатов MYSQL_RES через mysql_stmt_result_metadata().

Вы можете работать с буферами результатов через mysql_stmt_bind_result() так, чтобы mysql_stmt_fetch() автоматически возвращал данные в них.

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

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

Шаги выполнения

Чтобы подготовить и выполнить запрос, надо:

  1. Создайте готовый дескриптор запроса с помощью mysql_stmt_init() . Чтобы подготовить запрос на сервере, вызовите mysql_stmt_prepare() и передайте этой функции строку, содержащую запрос SQL.

  2. Если запрос произведет набор результатов, вызовите mysql_stmt_result_metadata(), чтобы получить метаданные о наборе результатов. Эти метаданные находятся самостоятельно в форме набора результатов, хотя и отдельно от того, который содержит строки, возвращенные запросом. Набор результатов метаданных указывает, сколько столбцов находится в результате и содержит информацию о каждом столбце.
  3. Установите значения любых параметров, используя mysql_stmt_bind_param(). Все параметры должны быть установлены. Иначе выполнение запроса возвращает ошибку или приводит к неожиданным результатам.
  4. Вызовите mysql_stmt_execute(), чтобы выполнить запрос.
  5. Если запрос производит набор результатов, используйте связанные буферы данных для того, чтобы получить значения строк, вызывая mysql_stmt_bind_result().
  6. Получите построчно данные в буферы, вызывая mysql_stmt_fetch() циклично, пока строки не кончатся.
  7. Повторите шаги 3-6 по мере необходимости, изменяя значения параметров и повторно выполняя запрос.

Когда mysql_stmt_prepare() вызван, протокол клиент-сервер MySQL выполняет эти действия:

Когда mysql_stmt_execute() вызван, протокол клиент-сервер MySQL выполняет эти действия:

Когда mysql_stmt_fetch() вызван, протокол клиент-сервер MySQL выполняет эти действия:

Если ошибка происходит, Вы можете получить код ошибки, сообщение об ошибке и код SQLSTATE, используя функции mysql_stmt_errno() , mysql_stmt_error() и mysql_stmt_sqlstate() соответственно.

Протоколирование подготовленных запросов

Для готовых запросов, которые выполнены с помощью функций C API mysql_stmt_prepare() и mysql_stmt_execute() сервер пишет строки Prepare и Execute в общий журнал регистрации запросов, чтобы Вы могли сказать, когда запрос был подготовлен и выполнен.

Предположите, что Вы готовите и выполняете запрос следующим образом:

  1. Вызываете mysql_stmt_prepare() для подготовки строки "SELECT ?".

  2. Вызываете mysql_stmt_bind_param(), чтобы привязать значение 3 к параметру в готовом запросе.
  3. Вызываете mysql_stmt_execute() для выполнения запроса.

В результате предыдущих действий сервер пишет следующие строки в общий журнал запросов:

Prepare  [1] SELECT ?
Execute  [1] SELECT 3

Каждая строка Prepare и Execute в журнале тегирована идентификатором [N] запроса, чтобы Вы могли отследить, из которого подготовленного запроса регистрируется что-либо. N положительное целое число. Если есть много подготовленных запросов, активных одновременно для клиента, N может быть больше, чем 1. Каждая строка Execute показывает готовый запрос после замены значений данными для параметра ?.

25.8.11. Описание функций подготовленных запросов в C API

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

Все функции, которые работают со структурой MYSQL_STMT, начинаются с префикса mysql_stmt_. Чтобы создать дескриптор, MYSQL_STMT используйте функцию mysql_stmt_init() .

25.8.11.1. mysql_stmt_affected_rows()

my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT *stmt)

Описание

mysql_stmt_affected_rows() может быть вызвана немедленно после выполнения запроса с помощью mysql_stmt_execute() . Это схоже с вызовом mysql_affected_rows(), но для готовых запросов.

Ошибки

Нет.

Пример

См. пример в разделе 25.8.11.10. mysql_stmt_execute().

25.8.11.2. mysql_stmt_attr_get()

my_bool mysql_stmt_attr_get(MYSQL_STMT *stmt, enum enum_stmt_attr_type option, void *arg)

Описание

Может использоваться, чтобы получить текущее значение признака запроса. Аргумент option это опция, которую Вы хотите получить, arg должен указать на переменную, которая должна содержать значение опции. Если опция целое число, arg должен указать на значение целого числа.

Возвращаемые значения

Ноль для успеха. Отличное от нуля, если option неизвестно.

Ошибки

Нет.

25.8.11.3. mysql_stmt_attr_set()

my_bool mysql_stmt_attr_set(MYSQL_STMT *stmt, enum enum_stmt_attr_type option, const void *arg)

Описание

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

Параметр option это опция, которую Вы хотите установить. arg значение для опции. arg должен указать на переменную, которая установлена в желаемое значение атрибута. Тип переменной обозначен в следующей таблице.

Опция Тип аргументаДействие
STMT_ATTR_UPDATE_MAX_LENGTH my_bool *Если установлено в 1, mysql_stmt_store_result() обновит в метаданных значение MYSQL_FIELD->max_length.
STMT_ATTR_CURSOR_TYPE unsigned long *Тип курсора для запроса, когда mysql_stmt_execute() вызван. *arg может быть CURSOR_TYPE_NO_CURSOR (по умолчанию) или CURSOR_TYPE_READ_ONLY.
STMT_ATTR_PREFETCH_ROWS unsigned long * Число строк для передачи от сервера во время использования курсора. *arg может быть в диапазоне от 1 до максимального значения unsigned long. Значение по умолчанию 1.

Если Вы используете опцию STMT_ATTR_CURSOR_TYPE с CURSOR_TYPE_READ_ONLY, курсор открыт для запроса, когда Вы вызываете mysql_stmt_execute(). Если уже есть открытый курсор от предыдущего mysql_stmt_execute() , это закрывает курсор прежде, чем открыть новый. mysql_stmt_reset() также закрывает любой открытый курсор прежде, чем подготовить запрос к повторному выполнению. mysql_stmt_free_result() закроет любой открытый курсор.

Если Вы открываете курсор для готового за запроса, mysql_stmt_store_result() не нужна, потому что та функция буферизует набор результатов на стороне клиента.

Возвращаемые значения

Ноль для успеха. Отличное от нуля, если неизвестно option.

Ошибки

Нет.

Пример

Следующий пример открывает курсор для готового запроса и определяет число возвращаемых за один раз строк в 5:

MYSQL_STMT *stmt;
int rc;
unsigned long type;
unsigned long prefetch_rows = 5;

stmt = mysql_stmt_init(mysql);
type = (unsigned long) CURSOR_TYPE_READ_ONLY;
rc = mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
/* ... check return value ... */
rc = mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS,
     (void*) &prefetch_rows);
/* ... check return value ... */

25.8.11.4. mysql_stmt_bind_param()

my_bool mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)

Описание

mysql_stmt_bind_param() используется, чтобы связать входные данные для маркеров параметра в запросе SQL, который передан mysql_stmt_prepare(). Это использует структуру MYSQL_BIND, чтобы снабдить данными. bind адрес массива структур MYSQL_BIND. Библиотека клиента ожидает, что массив будет содержать один элемент для каждого маркер параметра ?, который присутствует в запросе.

Предположите, что Вы готовите следующий запрос:

INSERT INTO mytbl VALUES(?,?,?)

Когда Вы связываете параметры, массив структур MYSQL_BIND должен содержать три элемента, которые могут быть объявлены так:

MYSQL_BIND bind[3];
Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки
Пример

См. пример в разделе 25.8.11.10. mysql_stmt_execute().

25.8.11.5. mysql_stmt_bind_result()

my_bool mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)

Описание

mysql_stmt_bind_result() используется, чтобы привязать выходные столбцы в наборе результатов к буферам длины и данных. Когда mysql_stmt_fetch() вызвана, чтобы принести данные, протокол клиент-сервер MySQL помещает данные для связанных столбцов в указанные буферы.

Все столбцы должны быть связаны с буферами до запроса mysql_stmt_fetch() . bind адрес массива структур MYSQL_BIND. Библиотека клиента ожидает, что массив будет содержать один элемент для каждого столбца набора результатов. Если Вы не связываете столбцы со структурами MYSQL_BIND, mysql_stmt_fetch() просто игнорирует данные. Буферы должны быть достаточно большими, чтобы содержать значения данных, потому что протокол не возвращает значения данных в кусках.

Столбец может быть связан в любое время, даже после того, как набор результатов был частично получен. Новая привязка вступает в силу в следующем вызове mysql_stmt_fetch(). Предположите, что приложение связывает столбцы в наборе результатов и вызывает mysql_stmt_fetch() . Протокол клиент-сервер возвращает данные в связанные буферы. Тогда предположим, что приложение связывает столбцы с иным набором буферов. Протокол помещает данные в недавно связанные буферы при следующем вызове mysql_stmt_fetch() .

Чтобы привязать столбец, приложение вызывает mysql_stmt_bind_result() и передает тип, адрес и длину выходного буфера, в который должно быть сохранено значение. Раздел 25.8.9 описывает членов каждого элемента MYSQL_BIND и то, как они должны быть установлены, чтобы получить выходные значения.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

25.8.11.6. mysql_stmt_close()

my_bool mysql_stmt_close(MYSQL_STMT *)

Описание

Закрывает готовый запрос. mysql_stmt_close() также освобождает дескриптор запроса, который указан stmt. Если у текущего запроса есть ожидание или непрочитанные результаты, эта функция отменяет их так, чтобы следующий запрос мог быть выполнен.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

25.8.11.7. mysql_stmt_data_seek()

void mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong offset)

Описание

Переходит на произвольную строку в наборе результатов запроса. offset задает номер строки и должно быть в диапазоне от 0 до mysql_stmt_num_rows(stmt)-1.

Эта функция требует, чтобы структура набора результатов содержала весь результат последнего выполненного запроса, таким образом, mysql_stmt_data_seek() может использоваться только в сочетании с mysql_stmt_store_result().

Возвращаемые значения

Нет.

Ошибки

Нет.

25.8.11.8. mysql_stmt_errno()

unsigned int mysql_stmt_errno(MYSQL_STMT *stmt)

Описание

Для запроса, определенного stmt, mysql_stmt_errno() возвращает код ошибки для последней вызванной функции API, которая может преуспеть или потерпеть неудачу. Возвращаемое значение 0 значит, что ошибка не произошла. Коды сообщений об ошибке клиента перечислены в заголовочном файле MySQL errmsg.h. Коды сообщений об ошибке сервера перечислены в mysqld_error.h.

Возвращаемые значения

Значение кода ошибки. Ноль если ошибка не произошла.

Ошибки

Нет.

25.8.11.9. mysql_stmt_error()

const char *mysql_stmt_error(MYSQL_STMT *stmt)

Описание

Для запроса stmt mysql_stmt_error() возвращает законченную нулем строку, содержащую сообщение об ошибке для последней функции API, которая может преуспеть или потерпеть неудачу. Пустая строка ("") возвращена, если ошибка не произошла. Любой из этих двух тестов может использоваться, чтобы проверить на ошибку:

if (*mysql_stmt_errno(stmt)) {
   // an error occurred
}
if (mysql_stmt_error(stmt)[0]) {
   // an error occurred
}

Язык сообщений об ошибках клиента может быть изменен перекомпиляцией библиотеки клиента MySQL. Вы можете выбрать сообщения об ошибках на нескольких различных языках.

Возвращаемые значения

Строка символов, которая описывает ошибку. Пустая строка, если ошибка не произошла.

Ошибки

Нет.

25.8.11.10. mysql_stmt_execute()

int mysql_stmt_execute(MYSQL_STMT *stmt)

Описание

mysql_stmt_execute() выполняет готовый запрос, связанный с дескриптором. В настоящее время связываемые значения маркера параметра посылаются серверу во время этого вызова, и сервер заменяет маркеры этими данными. Обработка запроса после mysql_stmt_execute() зависит от его типа:

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

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки
Пример

Следующий пример демонстрирует, как создать и заполнить таблицу, применяя mysql_stmt_init() , mysql_stmt_prepare(), mysql_stmt_param_count(), mysql_stmt_bind_param(), mysql_stmt_execute() и mysql_stmt_affected_rows(). Переменная mysql является допустимым дескриптором соединения. Для примера, который показывает, как получить данные, см. раздел 25.8.11.11. mysql_stmt_fetch().

#define STRING_SIZE 50
#define DROP_SAMPLE_TABLE "DROP TABLE IF EXISTS test_table"
#define CREATE_SAMPLE_TABLE "CREATE TABLE test_table(col1 INT,\
        col2 VARCHAR(40), col3 SMALLINT, col4 TIMESTAMP)"
#define INSERT_SAMPLE "INSERT INTO test_table(col1,col2,col3) \
        VALUES(?,?,?)"

MYSQL_STMT    *stmt;
MYSQL_BIND    bind[3];
my_ulonglong  affected_rows;
int     param_count;
short   small_data;
int     int_data;
char    str_data[STRING_SIZE];
unsigned long str_length;
my_bool is_null;

if (mysql_query(mysql, DROP_SAMPLE_TABLE)) {
   fprintf(stderr, " DROP TABLE failed\n");
   fprintf(stderr, " %s\n", mysql_error(mysql));
   exit(0);
}
if (mysql_query(mysql, CREATE_SAMPLE_TABLE)) {
   fprintf(stderr, " CREATE TABLE failed\n");
   fprintf(stderr, " %s\n", mysql_error(mysql));
   exit(0);
}
/* Prepare an INSERT query with 3 parameters */
/* (the TIMESTAMP column is not named; the server */
/*  sets it to the current date and time) */
stmt = mysql_stmt_init(mysql);
if (!stmt) {
   fprintf(stderr, " mysql_stmt_init(), out of memory\n");
   exit(0);
}
if (mysql_stmt_prepare(stmt, INSERT_SAMPLE, strlen(INSERT_SAMPLE))) {
   fprintf(stderr, " mysql_stmt_prepare(), INSERT failed\n");
   fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
   exit(0);
}
fprintf(stdout, " prepare, INSERT successful\n");
/* Get the parameter count from the statement */
param_count= mysql_stmt_param_count(stmt);
fprintf(stdout, " total parameters in INSERT: %d\n", param_count);
if (param_count != 3) /* validate parameter count */ {
   fprintf(stderr, " invalid parameter count returned by MySQL\n");
   exit(0);
}
/* Bind the data for all 3 parameters */
memset(bind, 0, sizeof(bind));
/* INTEGER PARAM */
/* This is a number type, so there is no need to specify buffer_length */
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= (char *)&int_data;
bind[0].is_null= 0;
bind[0].length= 0;
/* STRING PARAM */
bind[1].buffer_type= MYSQL_TYPE_STRING;
bind[1].buffer= (char *)str_data;
bind[1].buffer_length= STRING_SIZE;
bind[1].is_null= 0;
bind[1].length= &str_length;
/* SMALLINT PARAM */
bind[2].buffer_type= MYSQL_TYPE_SHORT;
bind[2].buffer= (char *)&small_data;
bind[2].is_null= &is_null;
bind[2].length= 0;
/* Bind the buffers */
if (mysql_stmt_bind_param(stmt, bind)) {
   fprintf(stderr, " mysql_stmt_bind_param() failed\n");
   fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
   exit(0);
}
/* Specify the data values for the first row */
int_data= 10; /* integer */
strncpy(str_data, "MySQL", STRING_SIZE); /* string  */
str_length= strlen(str_data);
/* INSERT SMALLINT data as NULL */
is_null= 1;
/* Execute the INSERT statement - 1*/
if (mysql_stmt_execute(stmt)) {
   fprintf(stderr, " mysql_stmt_execute(), 1 failed\n");
   fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
   exit(0);
}
/* Get the number of affected rows */
affected_rows= mysql_stmt_affected_rows(stmt);
fprintf(stdout, " total affected rows(insert 1): %lu\n",
        (unsigned long) affected_rows);
if (affected_rows != 1) /* validate affected rows */ {
   fprintf(stderr, " invalid affected rows by MySQL\n");
   exit(0);
}
/* Specify data values for second row, then re-execute the statement */
int_data= 1000;
strncpy(str_data, "The most popular Open Source database", STRING_SIZE);
str_length= strlen(str_data);
small_data= 1000;   /* smallint */
is_null= 0; /* reset */
/* Execute the INSERT statement - 2*/
if (mysql_stmt_execute(stmt)) {
   fprintf(stderr, " mysql_stmt_execute, 2 failed\n");
   fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
   exit(0);
}
/* Get the total rows affected */
affected_rows= mysql_stmt_affected_rows(stmt);
fprintf(stdout, " total affected rows(insert 2): %lu\n",
        (unsigned long) affected_rows);
if (affected_rows != 1) /* validate affected rows */ {
   fprintf(stderr, " invalid affected rows by MySQL\n");
   exit(0);
}
/* Close the statement */
if (mysql_stmt_close(stmt)) {
   fprintf(stderr, " failed while closing the statement\n");
   fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
   exit(0);
}

Для изучения полных примеров использования функций готовых запросов обратитесь к файлу tests/mysql_client_test.c. Этот файл может быть получен из набора исходных текстов MySQL (см. раздел 2.8. Установка MySQL из исходных текстов).

25.8.11.11. mysql_stmt_fetch()

int mysql_stmt_fetch(MYSQL_STMT *stmt)

Описание

mysql_stmt_fetch() возвращает следующую строку в наборе результатов. Это можно назвать только в то время, когда набор результатов существует, то есть, после вызова mysql_stmt_execute() для запроса, подобного SELECT, который производит набор результатов.

mysql_stmt_fetch() вернет данные о строке, используя буферы, связанные mysql_stmt_bind_result(). Это возвращает данные в буферах для всех столбцов в текущем наборе строк, длины будут возвращены в указатель length. Все столбцы должны быть связаны приложением прежде, чем оно будет вызывать mysql_stmt_fetch().

По умолчанию наборы результатов получены построчно с сервера. Чтобы буферизовать весь набор результатов на клиенте, вызовите mysql_stmt_store_result() после привязки буферов данных и перед запросом mysql_stmt_fetch().

Если полученное значение данных NULL, то значение *is_null соответствующей структуры MYSQL_BIND содержит TRUE (1). Иначе данные и его длина возвращены в элементах *buffer и *length, основанных на типе буфера, определенном приложением. У каждого числового и временного типа есть фиксированная длина, как перечислено в следующей таблице. Длина строковых типов зависит от длины фактического значения данных, как обозначено data_length.

Тип Длина
MYSQL_TYPE_TINY1
MYSQL_TYPE_SHORT2
MYSQL_TYPE_LONG4
MYSQL_TYPE_LONGLONG8
MYSQL_TYPE_FLOAT4
MYSQL_TYPE_DOUBLE8
MYSQL_TYPE_TIME sizeof(MYSQL_TIME)
MYSQL_TYPE_DATE sizeof(MYSQL_TIME)
MYSQL_TYPE_DATETIME sizeof(MYSQL_TIME)
MYSQL_TYPE_STRING data length
MYSQL_TYPE_BLOB data_length

В некоторых случаях Вы могли бы определить длину значения столбца прежде, чем получить его с помощью mysql_stmt_fetch() . Например, значение могло бы быть длинной строкой или объектом BLOB, для которого Вы хотите знать, сколько места должно быть выделено. Чтобы достигнуть этого, Вы можете использовать эти стратегии:

Возвращаемые значения
Возвращаемое значение Описание
0Успешно, данные были сохранены в буферы данных приложения.
1Ошибка произошла. Код ошибки и сообщение могут быть получены, вызывая mysql_stmt_errno() и mysql_stmt_error().
MYSQL_NO_DATAБольше строк/данных не существует.
MYSQL_DATA_TRUNCATED Усечение данных произошло.

MYSQL_DATA_TRUNCATED возвращается, когда сообщение об усечении включено. Чтобы определить, какие значения столбцов были усеченными, когда это значение возвращено, проверьте член error структур MYSQL_BIND, используемых для получения значений. Сообщение об усечении включено по умолчанию, но может управляться mysql_options() с опцией MYSQL_REPORT_DATA_TRUNCATION.

Ошибки
Пример

Следующий пример демонстрирует, как получить данные из таблицы, используя mysql_stmt_result_metadata(), mysql_stmt_bind_result() и mysql_stmt_fetch() . Этот пример ожидает получить две строки, вставленные примером, показанным в разделе 25.8.11.10. mysql_stmt_execute(). Переменная mysql является допустимым дескриптором соединения.

#define STRING_SIZE 50
#define SELECT_SAMPLE "SELECT col1, col2, col3, col4 \
                              FROM test_table"
MYSQL_STMT    *stmt;
MYSQL_BIND    bind[4];
MYSQL_RES     *prepare_meta_result;
MYSQL_TIME    ts;
unsigned long length[4];
int     param_count, column_count, row_count;
short   small_data;
int     int_data;
char    str_data[STRING_SIZE];
my_bool is_null[4];
my_bool error[4];

/* Prepare a SELECT query to fetch data from test_table */
stmt = mysql_stmt_init(mysql);
if (!stmt) {
   fprintf(stderr, " mysql_stmt_init(), out of memory\n");
   exit(0);
}
if (mysql_stmt_prepare(stmt, SELECT_SAMPLE, strlen(SELECT_SAMPLE))) {
   fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n");
   fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
   exit(0);
}
fprintf(stdout, " prepare, SELECT successful\n");
/* Get the parameter count from the statement */
param_count= mysql_stmt_param_count(stmt);
fprintf(stdout, " total parameters in SELECT: %d\n", param_count);
if (param_count != 0) /* validate parameter count */ {
   fprintf(stderr, " invalid parameter count returned by MySQL\n");
   exit(0);
}
/* Fetch result set meta information */
prepare_meta_result = mysql_stmt_result_metadata(stmt);
if (!prepare_meta_result) {
   fprintf(stderr, " mysql_stmt_result_metadata(), \
           returned no meta information\n");
   fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
   exit(0);
}
/* Get total columns in the query */
column_count= mysql_num_fields(prepare_meta_result);
fprintf(stdout, " total columns in SELECT statement: %d\n", column_count);
if (column_count != 4) /* validate column count */ {
   fprintf(stderr, " invalid column count returned by MySQL\n");
   exit(0);
}
/* Execute the SELECT query */
if (mysql_stmt_execute(stmt)) {
   fprintf(stderr, " mysql_stmt_execute(), failed\n");
   fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
   exit(0);
}
/* Bind the result buffers for all 4 columns before fetching them */
memset(bind, 0, sizeof(bind));
/* INTEGER COLUMN */
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= (char *)&int_data;
bind[0].is_null= &is_null[0];
bind[0].length= &length[0];
bind[0].error= &error[0];
/* STRING COLUMN */
bind[1].buffer_type= MYSQL_TYPE_STRING;
bind[1].buffer= (char *)str_data;
bind[1].buffer_length= STRING_SIZE;
bind[1].is_null= &is_null[1];
bind[1].length= &length[1];
bind[1].error= &error[1];
/* SMALLINT COLUMN */
bind[2].buffer_type= MYSQL_TYPE_SHORT;
bind[2].buffer= (char *)&small_data;
bind[2].is_null= &is_null[2];
bind[2].length= &length[2];
bind[2].error= &error[2];
/* TIMESTAMP COLUMN */
bind[3].buffer_type= MYSQL_TYPE_TIMESTAMP;
bind[3].buffer= (char *)&ts;
bind[3].is_null= &is_null[3];
bind[3].length= &length[3];
bind[3].error= &error[3];
/* Bind the result buffers */
if (mysql_stmt_bind_result(stmt, bind)) {
   fprintf(stderr, " mysql_stmt_bind_result() failed\n");
   fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
   exit(0);
}
/* Now buffer all results to client (optional step) */
if (mysql_stmt_store_result(stmt)) {
   fprintf(stderr, " mysql_stmt_store_result() failed\n");
   fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
   exit(0);
}
/* Fetch all rows */
row_count= 0;
fprintf(stdout, "Fetching results ...\n");
while (!mysql_stmt_fetch(stmt)) {
  row_count++;
  fprintf(stdout, "  row %d\n", row_count);
  /* column 1 */
  fprintf(stdout, "   column1 (integer)  : ");
  if (is_null[0]) fprintf(stdout, " NULL\n");
  else fprintf(stdout, " %d(%ld)\n", int_data, length[0]);
  /* column 2 */
  fprintf(stdout, "   column2 (string)   : ");
  if (is_null[1]) fprintf(stdout, " NULL\n");
  else fprintf(stdout, " %s(%ld)\n", str_data, length[1]);
  /* column 3 */
  fprintf(stdout, "   column3 (smallint) : ");
  if (is_null[2]) fprintf(stdout, " NULL\n");
  else fprintf(stdout, " %d(%ld)\n", small_data, length[2]);
  /* column 4 */
  fprintf(stdout, "   column4 (timestamp): ");
  if (is_null[3]) fprintf(stdout, " NULL\n");
  else fprintf(stdout, " %04d-%02d-%02d %02d:%02d:%02d (%ld)\n",
               ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second,
               length[3]);
  fprintf(stdout, "\n");
}
/* Validate rows fetched */
fprintf(stdout, " total rows fetched: %d\n", row_count);
if (row_count != 2) {
   fprintf(stderr, " MySQL failed to return all rows\n");
   exit(0);
}
/* Free the prepared result metadata */
mysql_free_result(prepare_meta_result);
/* Close the statement */
if (mysql_stmt_close(stmt)) {
   fprintf(stderr, " failed while closing the statement\n");
   fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
   exit(0);
}

25.8.11.12. mysql_stmt_fetch_column()

int mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind, unsigned int column, unsigned long offset)

Описание

Получает один столбец текущей строки набора результатов. bind обеспечивает буфер, куда данные должны быть помещены. Это должно быть настроено так же, как и mysql_stmt_bind_result(). column указывает, который столбец нужен. Первый столбец пронумерован как 0. offset смещение в пределах значения данных, где начать получать данные. Это может использоваться для того, чтобы принести значение данных по частям. Начало значения имеет offset 0.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

25.8.11.13. mysql_stmt_field_count()

unsigned int mysql_stmt_field_count(MYSQL_STMT *stmt)

Описание

Возвращает число столбцов для нового запроса для обработчика запроса. Это значение ноль для таких запросов, как INSERT или DELETE, которые не производят наборы результатов.

mysql_stmt_field_count() может быть вызвана после того, как Вы подготовили запрос вызовом mysql_stmt_prepare().

Возвращаемые значения

Целое число без знака, представляющее число столбцов в наборе результатов.

Ошибки

Нет.

25.8.11.14. mysql_stmt_free_result()

my_bool mysql_stmt_free_result(MYSQL_STMT *stmt)

Описание

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

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

25.8.11.15. mysql_stmt_init()

MYSQL_STMT *mysql_stmt_init(MYSQL *mysql)

Описание

Создает дескриптор MYSQL_STMT. Дескриптор должен быть освобожден с помощью mysql_stmt_close(MYSQL_STMT *).

Возвращаемые значения

Указатель на структуру MYSQL_STMT в случае успеха. NULL, если мало памяти.

Ошибки

25.8.11.16. mysql_stmt_insert_id()

my_ulonglong mysql_stmt_insert_id(MYSQL_STMT *stmt)

Описание

Возвращает значение, произведенное для столбца AUTO_INCREMENT подготовленным запросом INSERT или UPDATE. Используйте эту функцию после того, как Вы выполнили готовый запрос INSERT на таблице, которая содержит поле AUTO_INCREMENT field.

Возвращаемые значения

Значение для столбца AUTO_INCREMENT, которое было автоматически произведено или явно установлено во время выполнения готового запроса, или значение, произведенное функцией LAST_INSERT_ID(expr). Возвращаемое значение неопределено, если запрос не устанавливает значение AUTO_INCREMENT.

Ошибки

Нет.

25.8.11.17. mysql_stmt_next_result()

int mysql_stmt_next_result(MYSQL_STMT *mysql)

Описание

Эта функция используется, когда Вы используете подготовленный запрос CALL, чтобы выполнить хранимые процедуры, которые могут возвратить много наборов результатов. Используйте цикл для вызова mysql_stmt_next_result(), чтобы определить, есть ли еще результаты. Если процедура имеет параметры OUT или INOUT, их значения будут возвращены как набор результатов единственной строки после любых других наборов результатов. Значения появятся в порядке, в котором они объявлены в списке параметров процедуры.

mysql_stmt_next_result() возвращает состояние, чтобы указать, существует ли больше результатов. Если mysql_stmt_next_result() возвращает ошибку, нет больше результатов.

Перед каждым вызовом mysql_stmt_next_result() Вы должны вызвать mysql_stmt_free_result() для текущего результата, если это произвело набор результатов (а не только состояние результата).

После вызова mysql_stmt_next_result() состояние аналогично тому, если Вы вызвали mysql_stmt_execute(). Это означает, что Вы можете вызвать mysql_stmt_bind_result(), mysql_stmt_affected_rows() и т.д.

Также возможно проверить, есть ли еще результаты, вызывая mysql_more_results() . Однако, эта функция не изменяет состояние соединения, так что, если это возвращает истину, Вы должны вызывать mysql_stmt_next_result(), чтобы обратиться к следующему результату.

Для примера, который показывает, как использовать mysql_stmt_next_result(), см. раздел 25.8.20 .

Возвращаемые значения
Возвращаемое значениеОписание
0Успешно и есть еще результаты.
-1Успешно и нет больше результатов.
>0Ошибка произошла
Ошибки

25.8.11.18. mysql_stmt_num_rows()

my_ulonglong mysql_stmt_num_rows(MYSQL_STMT *stmt)

Описание

Возвращает число строк в наборе результатов.

Использование mysql_stmt_num_rows() зависит от того, использовали ли Вы mysql_stmt_store_result(), чтобы буферизовать весь набор результатов в дескрипторе запроса. Если Вы используете mysql_stmt_store_result(), mysql_stmt_num_rows() может быть вызван немедленно. Иначе количество строк недоступно, если Вы не считаете строки, пока забираете их.

mysql_stmt_num_rows() предназначен для использования с запросами, которые возвращают набор результатов, например, SELECT. Для запросов типа INSERT, UPDATE или DELETE число обработанных строк может быть получено с помощью mysql_stmt_affected_rows().

Возвращаемые значения

Число строк в наборе результатов.

Ошибки

Нет.

25.8.11.19. mysql_stmt_param_count()

unsigned long mysql_stmt_param_count(MYSQL_STMT *stmt)

Описание

Возвращает число маркеров параметра, существующих в готовом запросе.

Возвращаемые значения

unsigned long integer, представляющее число параметров в запросе.

Ошибки

Нет.

25.8.11.20. mysql_stmt_param_metadata()

MYSQL_RES *mysql_stmt_param_metadata(MYSQL_STMT *stmt)

Эта функция в настоящее время ничего не делает.

25.8.11.21. mysql_stmt_prepare()

int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *stmt_str, unsigned long length)

Описание

Учитывая дескриптор, возвращенный mysql_stmt_init(), готовит запрос SQL, на который указывает строка stmt_str и возвращает значение состояния. Строковая длина должна быть дана параметром length. Строка должна состоять из единственного запроса SQL. Вы не должны добавить заканчивающую точку с запятой (;) или \g.

Приложение может включать один или более маркеров параметра в запрос SQL, встраивая вопросительный знак (?) в SQL-строку в соответствующих позициях.

Маркеры являются законными только в определенных местах в заявлениях SQL. Например, они разрешаются в списке VALUES() запроса INSERT (чтобы определить значения столбцов для строки) или в сравнении со столбцом в предложении WHERE, чтобы определить сравнительное значение. Однако, они не разрешаются для идентификаторов (таких как имена таблиц или имена столбцов) или в определении обоих операндов бинарного оператора, подобного =. Последнее ограничение необходимо, потому что было бы невозможно определить тип параметра. Вообще, параметры являются законными только в командах Data Manipulation Language (DML), а не в Data Definition Language (DDL).

Маркеры параметра должны быть привязаны к используемым переменным приложения с помощью mysql_stmt_bind_param() прежде, чем выполнить запрос.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

Если подготовительная работа была неудачна (то есть, mysql_stmt_prepare() вернула не 0), сообщение об ошибке может быть получено посредством mysql_stmt_error().

25.8.11.22. mysql_stmt_reset()

my_bool mysql_stmt_reset(MYSQL_STMT *stmt)

Описание

Сбрасывает готовый запрос на клиенте и сервере к состоянию после подготовки. Это сбрасывает запрос на сервере, данные, посланные через mysql_stmt_send_long_data(), небуферизованные наборы результатов и текущие ошибки. Это не очищает привязку или сохраненные наборы результатов. Сохраненные наборы результатов будут очищены при выполнении готового или закрытии готового запроса.

Чтобы повторно подготовить запрос, примените mysql_stmt_prepare() .

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

25.8.11.23. mysql_stmt_result_metadata()

MYSQL_RES *mysql_stmt_result_metadata(MYSQL_STMT *stmt)

Описание

Если к mysql_stmt_prepare() прошел запрос, который производит набор результатов, mysql_stmt_result_metadata() возвращает метаданные о наборе результатов в форме указателя на структуру MYSQL_RES, которая может использоваться, чтобы обработать метаинформацию, такую как число полей и информация об отдельных полях. Этот указатель набора результатов можно передать как параметр любой из основанных на полях функций API, которые обрабатывают метаданные о наборе результатов, такие как:

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

Набор результатов, возвращенный mysql_stmt_result_metadata() содержит только метаданные. Это не содержит результатов строки. Строки получены при использовании дескриптора запроса в mysql_stmt_fetch().

Возвращаемые значения

Структура результата MYSQL_RES. NULL, если никакой метаинформации не существует для готового запроса.

Ошибки

25.8.11.24. mysql_stmt_row_seek()

MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT *stmt, MYSQL_ROW_OFFSET offset)

Описание

Устанавливает курсор строки в произвольную строку в наборе результатов. Значение offset определяет смещение строки, которое должно быть значением, возвращенным из mysql_stmt_row_tell() или mysql_stmt_row_seek(). Это значение не номер строки, если Вы хотите перейти на строку в пределах набора результатов по номеру, надо использовать mysql_stmt_data_seek().

Эта функция требует, чтобы структура набора результатов содержала весь результат запроса, таким образом mysql_stmt_row_seek() может использоваться только вместе с mysql_stmt_store_result().

Возвращаемые значения

Предыдущее значение курсора строки. Это значение можно передать последующему вызову mysql_stmt_row_seek().

Ошибки

Нет.

25.8.11.25. mysql_stmt_row_tell()

MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT *stmt)

Описание

Возвращает текущую позицию курсора строки для последнего вызова mysql_stmt_fetch() . Это значение может использоваться в качестве параметра mysql_stmt_row_seek().

Вы должны использовать mysql_stmt_row_tell() только после mysql_stmt_store_result().

Возвращаемые значения

Текущее смещение курсора строки.

Ошибки

Нет.

25.8.11.26. mysql_stmt_send_long_data()

my_bool mysql_stmt_send_long_data(MYSQL_STMT *stmt, unsigned int parameter_number, const char *data, unsigned long length)

Описание

Позволяет приложению послать данные параметров серверу в кусках (или (chunks). Вызовите эту функцию после mysql_stmt_bind_param() и перед mysql_stmt_execute() . Это можно вызвать многократно, чтобы послать части символьного столбца или двоичные данные, которые должны быть одним из типов данных TEXT или BLOB.

parameter_number указывает, который параметр связать с данными. Параметры пронумерованы, начиная с 0. data указатель на буфер, содержащий данные, которые будут посланы, и length указывает на число байтов в буфере.

Следующий вызов mysql_stmt_execute() игнорирует связыванные буферы для всех параметров, которые использовались с mysql_stmt_send_long_data() с последнего mysql_stmt_execute() или mysql_stmt_reset().

Если Вы хотите сбросить посланные данные, Вы можете сделать это с помощью mysql_stmt_reset() .

Системная переменная max_allowed_packet управляет максимальным размером значений параметра, которые можно послать с помощью mysql_stmt_send_long_data().

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки
Пример

Следующий пример демонстрирует, как послать данные для столбца TEXT кусками. Это вставляет значение данных 'MySQL - The most popular Open Source database' в столбец text_column. Переменная mysql является допустимым дескриптором соединения.

#define INSERT_QUERY "INSERT INTO \
                     test_long_data(text_column) VALUES(?)"

MYSQL_BIND bind[1];
long length;

stmt = mysql_stmt_init(mysql);
if (!stmt) {
   fprintf(stderr, " mysql_stmt_init(), out of memory\n");
   exit(0);
}
if (mysql_stmt_prepare(stmt, INSERT_QUERY, strlen(INSERT_QUERY))) {
   fprintf(stderr, "\n mysql_stmt_prepare(), INSERT failed");
   fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
   exit(0);
}
memset(bind, 0, sizeof(bind));
bind[0].buffer_type= MYSQL_TYPE_STRING;
bind[0].length= &length;
bind[0].is_null= 0;
/* Bind the buffers */
if (mysql_stmt_bind_param(stmt, bind)) {
   fprintf(stderr, "\n param bind failed");
   fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
   exit(0);
}
/* Supply data in chunks to server */
if (mysql_stmt_send_long_data(stmt,0,"MySQL",5)) {
   fprintf(stderr, "\n send_long_data failed");
   fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
   exit(0);
}
/* Supply the next piece of data */
if (mysql_stmt_send_long_data(stmt,0,
   " - The most popular Open Source database",40)) {
   fprintf(stderr, "\n send_long_data failed");
   fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
   exit(0);
}
/* Now, execute the query */
if (mysql_stmt_execute(stmt)) {
   fprintf(stderr, "\n mysql_stmt_execute failed");
   fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
   exit(0);
}

25.8.11.27. mysql_stmt_sqlstate()

const char *mysql_stmt_sqlstate(MYSQL_STMT *stmt)

Описание

Для запроса, определенного stmt, mysql_stmt_sqlstate() возвращает законченную нулем строку, содержащую код ошибки SQLSTATE для последнего вызванного готового запроса. Код ошибки состоит из пяти символов. "00000" означает "нет ошибки". Значения определены ANSI SQL и ODBC.

Не все ошибки MySQL отображены на коды SQLSTATE. Значение "HY000" (general error) используется для неотображенных ошибок.

Возвращаемые значения

Законченная нулем строка символов, содержащая код ошибки SQLSTATE.

25.8.11.28. mysql_stmt_store_result()

int mysql_stmt_store_result(MYSQL_STMT *stmt)

Описание

Наборы результатов, произведены вызовом mysql_stmt_execute() для выполнения подготовленных SQL-запросов, подобных SELECT , SHOW, DESCRIBE и EXPLAIN. По умолчанию наборы результатов для успешно выполненных готовых запросов не буферизованы в клиенте и mysql_stmt_fetch() забирает их по одному с сервера. Чтобы заставить полный набор результатов буферизоваться в клиенте, вызовите mysql_stmt_store_result() после привязки буферов данных с mysql_stmt_bind_result() и перед mysql_stmt_fetch() для получения строк. Пример есть в разделе 25.8.11.11. mysql_stmt_fetch().

mysql_stmt_store_result() является опциональным для обработки набора результатов, если Вы не будете вызывать функции mysql_stmt_data_seek(), mysql_stmt_row_seek() или mysql_stmt_row_tell(). Эти функции требуют позиционируемого набора результатов.

Не надо вызывать mysql_stmt_store_result() после выполнения запроса SQL, который не производит набор результатов, но если Вы так сделаете, это ничему не повредит. Вы можете проверить, произвел ли запрос набор результатов, проверяя, вернет ли mysql_stmt_result_metadata() NULL.

MySQL по умолчанию не вычисляет MYSQL_FIELD->max_length для всех столбцов в mysql_stmt_store_result() потому, что вычисление этого замедлило бы mysql_stmt_store_result() значительно, а большинство приложений не нуждается в max_length. Если Вы хотите, чтобы max_length обновлялось, вызовите mysql_stmt_attr_set(MYSQL_STMT, STMT_ATTR_UPDATE_MAX_LENGTH, &flag) , чтобы это включить. См. раздел 25.8.11.3. mysql_stmt_attr_set().

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

Ошибки

25.8.12. Описание функций потоков C API

25.8.12.1. my_init()

void my_init(void)

Описание

my_init() инициализирует некоторые глобальные переменные MySQL. Это также вызывает mysql_thread_init() для этого потока.

Необходимо вызвать my_init() в фазе инициализации использования программы библиотеки MySQL. Однако, my_init() автоматически вызывается mysql_init(), mysql_library_init() , mysql_server_init() и mysql_connect(). Если Вы гарантируете, что Ваша программа вызывает одну из этих функций перед любыми вызовами MySQL, нет потребности вызвать my_init() явно.

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

#include <my_global.h>
#include <my_sys.h>
Возвращаемые значения

Нет.

25.8.12.2. mysql_thread_end()

void mysql_thread_end(void)

Описание

Вызовите эту функцию перед запросом pthread_exit() для освобождения памяти, выделенной mysql_thread_init() .

mysql_thread_end() не вызывается автоматически библиотекой клиента . До MySQL 5.7.9 это нужно вызвать для каждого обращения к mysql_thread_init() , чтобы избежать утечки памяти. С MySQL 5.7.9 внутренности C API были переделаны, чтобы уменьшить количество информации, выделенной mysql_thread_init() , это должно быть освобождено mysql_thread_end() :

Возвращаемые значения

Нет.

25.8.12.3. mysql_thread_init()

my_bool mysql_thread_init(void)

Описание

Эта функция должна быть вызвана первой в пределах каждого создаваемого потока, чтобы инициализировать определенные для потока переменные. Однако, Вы не должны обязательно вызывать это явно: mysql_thread_init() автоматически вызывает my_init(), которая вызывается из mysql_init() , mysql_library_init() , mysql_server_init() и mysql_connect(). Если Вы вызываете какую-либо из этих функций, mysql_thread_init() будет вызвана.

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

25.8.12.4. mysql_thread_safe()

unsigned int mysql_thread_safe(void)

Описание

Эта функция указывает, собрана ли библиотека клиента как безопасная для потока.

Возвращаемые значения

1, если библиотека клиента безопасна для потока, 0 иначе.

25.8.13. Описание функций C API встроенного сервера

Приложения MySQL могут быть написаны, чтобы использовать встроенный сервер. Чтобы написать такое приложение, Вы должны его скомпоновать с библиотекой libmysqld, используя параметр -lmysqld вместо -lmysqlclient. Однако, требования инициализировать и завершить библиотеку являются теми же самыми, пишете ли Вы приложение-клиент или то, которое использует встроенный сервер: вызовите mysql_library_init() , чтобы инициализировать библиотеку и mysql_library_end() , когда Вы с ней закончите.

25.8.13.1. mysql_server_init()

int mysql_server_init(int argc, char **argv, char **groups)

Описание

Эта функция инициализирует библиотеку MySQL, она должна быть вызвана прежде, чем Вы вызовете любую другую функцию MySQL. Однако, mysql_server_init() устарела, поэтому Вы должны вызывать mysql_library_init() .

Возвращаемые значения

Ноль для успеха. Отличный от нуля, если ошибка произошла.

25.8.13.2. mysql_server_end()

void mysql_server_end(void)

Описание

Эта функция завершает библиотеку MySQL, она должна быть вызвана, когда Вы завершаете работу с MySQL. Но mysql_server_end() устарела, поэтому вместо нее надо использовать mysql_library_end() .

Возвращаемые значения

Нет.

25.8.14. Функции плагинов C API

Этот раздел описывает функции, используемые для клиентского плагина API. Они включают управление плагинами клиента. Для описания структуры st_mysql_client_plugin, используемой этими функциями, см. раздел 26.2.4.2.3. Дескриптор плагина клиента.

Маловероятно, что программа клиента должна вызвать функции в этом разделе. Например, клиент, который поддерживает использование плагинов аутентификации, обычно загружает плагин вызовом mysql_options() для установки опций MYSQL_DEFAULT_AUTH и MYSQL_PLUGIN_DIR:

char *plugin_dir = "path_to_plugin_dir";
char *default_auth = "plugin_name";

/* ... process command-line options ... */

mysql_options(&mysql, MYSQL_PLUGIN_DIR, plugin_dir);
mysql_options(&mysql, MYSQL_DEFAULT_AUTH, default_auth);

Как правило, программа также примет опции --plugin-dir и --default-auth, которые позволяют пользователям переопределить значения по умолчанию.

25.8.14.1. mysql_client_find_plugin()

struct st_mysql_client_plugin *mysql_client_find_plugin(MYSQL *mysql, const char *name, int type)

Описание

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

Возвращаемые значения

Указатель на плагин для успеха. NULL если ошибка произошла.

Ошибки

Чтобы проверить на ошибки, вызовите функцию mysql_error() или mysql_errno().

Пример
MYSQL mysql;
struct st_mysql_client_plugin *p;

if ((p = mysql_client_find_plugin(&mysql, "myplugin",
                                  MYSQL_CLIENT_AUTHENTICATION_PLUGIN, 0))) {
   printf("Plugin version: %d.%d.%d\n", p->version[0], p->version[1],
          p->version[2]);
}

25.8.14.2. mysql_client_register_plugin()

struct st_mysql_client_plugin *mysql_client_register_plugin(MYSQL *mysql, struct st_mysql_client_plugin *plugin)

Описание

Добавляет структуру к списку загруженных плагинов. Ошибка происходит, если плагин уже загружен. Определите параметры следующим образом:

Возвращаемые значения

Указатель на плагин для успеха. NULL если ошибка произошла.

Ошибки

Чтобы проверить на ошибки, вызовите функцию mysql_error() или mysql_errno().

25.8.14.3. mysql_load_plugin()

struct st_mysql_client_plugin *mysql_load_plugin(MYSQL *mysql, const char *name, int type, int argc, ...)

Описание

Загружает плагин клиента MySQL, определенный по имени и типу. Ошибка происходит, если тип недопустим, или плагин не может быть загружен.

Невозможно загрузить много плагины того же самого типа. Ошибка происходит, если Вы пытаетесь загрузить плагин уже загруженного типа. Определите параметры следующим образом:

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

shell> export LIBMYSQL_PLUGINS="myplugin1;myplugin2"

Плагины, названные в LIBMYSQL_PLUGINS загружены, когда программа клиента вызывает mysql_library_init(). Ни о какой ошибке не сообщается, если проблемы происходят, загружая эти плагины.

Переменная окружения LIBMYSQL_PLUGIN_DIR может быть установлена в путь к каталогу, в котором можно искать плагины клиента. Эта переменная используется двумя способами:

Возвращаемые значения

Указатель на плагин, если он был загружен успешно. NULL, если ошибка произошла.

Ошибки

Для проверки на ошибки, используйте функцию mysql_error() или mysql_errno().

Пример
MYSQL mysql;

if (!mysql_load_plugin(&mysql, "myplugin",
                       MYSQL_CLIENT_AUTHENTICATION_PLUGIN, 0)) {
   fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
   exit(-1);
}

25.8.14.4. mysql_load_plugin_v()

struct st_mysql_client_plugin *mysql_load_plugin_v(MYSQL *mysql, const char *name, int type, int argc, va_list args)

Описание

Эта функция эквивалентна mysql_load_plugin() , но это принимает va_list вместо переменной со списком параметров.

25.8.14.5. mysql_plugin_options()

int mysql_plugin_options(struct st_mysql_client_plugin *plugin, const char *option, const void *value)

Описание

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

Возвращаемые значения

Ноль для успеха, 1, если ошибка произошла. Если у плагина есть обработчик опции, он должен также возвратить ноль для успеха и 1, если ошибка произошла.

25.8.15. Основные вопросы и проблемы при использовании C API

25.8.15.1. Почему Why mysql_store_result() иногда возвращает NULL после успешной mysql_query()

Это возможно. Когда это происходит, это означает, что одно из следующих условий произошло:

Вы можете всегда проверить, должен ли запрос привести к непустому результату, вызывая mysql_field_count() . Если mysql_field_count() вернет 0, результат пуст, и последний запрос был запросом, который не делает возвращаемых значений (например, INSERT или DELETE). Если mysql_field_count() возвращает ненулевое значение, запрос должен был привести к непустому результату. См. описание функции mysql_field_count() .

Вы можете проверить ситуацию на ошибку, вызывая mysql_error() или mysql_errno().

25.8.15.2. Какие результаты Вы можете получить от запроса

В дополнение к набору результатов, возвращенному запросом, Вы можете также получить следующую информацию:

25.8.15.3. Как получить уникальный ID для последней вставленной строки

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

Вы можете проверить из своих приложений C, было ли значение сохранено в столбец AUTO_INCREMENT, выполняя следующий код (который предполагает, что Вы проверили, что запрос прошел нормально). Это определяет, был ли запрос INSERT с индексом AUTO_INCREMENT:

if ((result = mysql_store_result(&mysql)) == 0 &&
    mysql_field_count(&mysql) == 0 &&
    mysql_insert_id(&mysql) != 0) {
    used_id = mysql_insert_id(&mysql);
}

Когда новое значение было произведено AUTO_INCREMENT, Вы можете также получить его, выполняя SELECT LAST_INSERT_ID() через mysql_query() и получая значение из набора результатов.

Когда вставляется много значений, вернется последнее автоматически увеличенное значение. Для LAST_INSERT_ID() последний произведенный ID хранится на сервере с привязкой к соединению. Это не изменено другим клиентом. Это даже не изменено, если Вы обновляете другой столбец AUTO_INCREMENT с неволшебным значением (то есть, значение, которое не является NULL или 0). Использование функции LAST_INSERT_ID() и столбцов AUTO_INCREMENT одновременно для многих клиентов допустимо. Каждый клиент получит последний вставленный ID для последнего запроса, который выполнял этот клиент.

Если Вы хотите использовать ID, который был произведен для одной таблицы, и вставить его во вторую таблицу, Вы можете использовать запрос SQL:

INSERT INTO foo (auto,text)
    VALUES(NULL,'text');   # generate ID by inserting NULL
INSERT INTO foo2 (id,text)
    VALUES(LAST_INSERT_ID(),'text');  # use ID in second table

mysql_insert_id() возвращает значение, сохраненное в столбце AUTO_INCREMENT, произведено ли это значение автоматически или было определено как явное значение. LAST_INSERT_ID() возвращает только автоматически произведенные значения AUTO_INCREMENT. Если Вы сохраняете явное значение, кроме NULL или 0, это не затрагивает значение, возвращенное LAST_INSERT_ID().

25.8.16. Управление автоматическим пересоединением

Библиотека клиента MySQL может выполнить автоматическое пересоединение к серверу, если находит, что соединение оборвалось, когда Вы пытаетесь послать запрос серверу. Если автоматическое пересоединение включено, библиотека попытается связаться зново и послать запрос.

По умолчанию пересоединение выключено. Если для Вашего приложения важно знать, что соединение было оборвано, убедитесь, что пересоединение выключено. Чтобы гарантировать это, вызовите mysql_options() с опцией MYSQL_OPT_RECONNECT:

my_bool reconnect = 0;
mysql_options(&mysql, MYSQL_OPT_RECONNECT, &reconnect);

Если соединение оборвалось эффект mysql_ping() зависит от состояния auto-reconnect. Если пересоединение включено, mysql_ping() выполняет повторное соединение. Иначе это возвращает ошибку.

Некоторые программы-клиенты могли бы обеспечить способность управления автоматическим пересоединением. Например, mysql повторно соединяется по умолчанию, но опция --skip-reconnect может использоваться, чтобы подавить это поведение.

Если автоматическое пересоединение действительно происходит (например, в результате запроса mysql_ping()), нет никакого явного признака этого. Чтобы проверить на пересоединение, вызовите mysql_thread_id(), чтобы получить оригинальный идентификатор соединения перед запросом mysql_ping(), затем вызовите mysql_thread_id() снова, чтобы видеть, изменился ли идентификатор.

Автоматическое пересоединение может быть удобным, потому что Вы не должны осуществить свое собственное, но если пересоединение действительно происходит, несколько аспектов соединения сброшены на стороне сервера, и Ваше приложение не будет об этом предупреждено.

Связанный с соединением статус затронут следующим образом:

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

25.8.17. Поддержка C API выполнения нескольких запросов сразу

По умолчанию mysql_query() и mysql_real_query() интерпретирует строковый параметр как единственный запрос, который будет выполнен, а Вы обрабатываете результат согласно тому, производит ли запрос набор результатов (ряд строк, как для SELECT или количество затронутых строк, как для INSERT , UPDATE и т.п.).

MySQL также поддерживает выполнение строки, содержащей много запросов, разделенных точкой с запятой (;). Эта способность включена специальными опциями, которые определены также, когда Вы соединяетесь с сервером с помощью mysql_real_connect() или вызовом mysql_set_server_option() после соединения.

Выполнение строки с несколькими запросами может произвести много наборов результатов или индикаторов количества строк. Обработка этих результатов вовлекает другой подход, чем для случая единственного запроса: после обработки результата первого запроса необходимо проверить, существуют ли еще результаты и обработать их в свою очередь. Чтобы поддержать обработку многих результатов C API включает функции mysql_more_results() и mysql_next_result() . Эти функции используются в цикле, который повторяется, пока еще есть результаты. Отказ обработать результат этим путем может привести к сбою соединения с сервером.

Обработка нескольких результатов также требуется, если Вы выполняете вызов CALL для хранимых процедур. У резултатов хранимой процедуры есть эти характеристики:

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

Чтобы включить выполнению многих запросов и обработку результата, следующие опции могут использоваться:

Следующая процедура обрисовывает в общих чертах предложенную стратегию обработки для запросов:

  1. Передайте CLIENT_MULTI_STATEMENTS в mysql_real_connect(), чтобы полностью включить выполнение множественных запросов и обработку многих результатов.

  2. После вызова mysql_query() или mysql_real_query() и подтверждения, что все прошло нормально, входите в цикл, в пределах которого Вы обрабатываете результаты запросов.
  3. Для каждой итерации цикла обработайте текущий результат запроса, получая набор результатов или количество затронутых строк. Если ошибка происходит, выйдите из цикла.
  4. В конце цикла вызовите mysql_next_result(), чтобы проверить, существует ли другой результат и если он есть, начинайте работу с ним. Если больше результатов нет, выходите из цикла.

Одно возможное выполнение предыдущей стратегии показывают следующее. Заключительная часть цикла может быть уменьшена до простого теста: возвращает ли mysql_next_result() не 0.

/* connect to server with the CLIENT_MULTI_STATEMENTS option */
if (mysql_real_connect (mysql, host_name, user_name, password,
    db_name, port_num, socket_name, CLIENT_MULTI_STATEMENTS) == NULL) {
   printf("mysql_real_connect() failed\n");
   mysql_close(mysql);
   exit(1);
}

/* execute multiple statements */
status = mysql_query(mysql, "DROP TABLE IF EXISTS test_table;\
                     CREATE TABLE test_table(id INT);\
                     INSERT INTO test_table VALUES(10);\
                     UPDATE test_table SET id=20 WHERE id=10;\
                     SELECT * FROM test_table;\
                     DROP TABLE test_table");
if (status) {
   printf("Could not execute statement(s)");
   mysql_close(mysql);
   exit(0);
}

/* process each statement result */
do {
  /* did current statement return data? */
  result = mysql_store_result(mysql);
  if (result) {
     /* yes; process rows and free the result set */
     process_result_set(mysql, result);
     mysql_free_result(result);
  }
  else    /* no result set or error */
  {
    if (mysql_field_count(mysql) == 0) {
       printf("%lld rows affected\n", mysql_affected_rows(mysql));
    }
    else  /* some error occurred */
    {
      printf("Could not retrieve result set\n");
      break;
    }
  }
  /* more results? -1 = no, >0 = error, 0 = yes (keep looping) */
  if ((status = mysql_next_result(mysql)) > 0)
     printf("Could not execute statement\n");
} while (status == 0);
mysql_close(mysql);

25.8.18. Проблемы подготовленных запросов в C API

Это список известных в настоящее время проблем с готовыми запросами:

25.8.19. Обработка даты и времени подготовленными запросами в C API

Двоичный протокол позволяет Вам послать и получить значения даты и времени (DATE, TIME, DATETIME и TIMESTAMP), используя структуру MYSQL_TIME. Члены этой структуры описаны в разделе 25.8.9. Структуры данных подготовленных запросов в C API.

Чтобы послать временные значения данных, создайте готовый запрос, применив mysql_stmt_prepare() . Потом, перед запросом mysql_stmt_execute() для выполнения запроса, используйте следующую процедуру, чтобы настроить каждый параметр:

  1. В структуре MYSQL_BIND связанной со значением данных установите член buffer_type к типу, который указывает, какое временное значение Вы посылаете. Для значений DATE, TIME, DATETIME или TIMESTAMP установите buffer_type соответственно в MYSQL_TYPE_DATE, MYSQL_TYPE_TIME, MYSQL_TYPE_DATETIME или MYSQL_TYPE_TIMESTAMP.

  2. Установите член buffer структуры MYSQL_BIND к адресу структуры MYSQL_TIME, в которой Вы передаете временное значение.
  3. Заполните члены структуры MYSQL_TIME, которые являются подходящими для типа временного значения.

Используйте mysql_stmt_bind_param(), чтобы связать данные о параметре с запросом. Тогда Вы можете вызвать mysql_stmt_execute() .

Чтобы получить временные значения, процедура подобна, за исключением того, что Вы устанавливаете buffer_type к типу, имеющему значение, которое Вы ожидаете получить, а buffer в адресу структуры MYSQL_TIME, в которую должно быть помещено возвращенное значение. Используйте mysql_stmt_bind_result(), чтобы привязать буферы с запросом после mysql_stmt_execute() и прежде, чем получить результаты.

Вот простой пример, который вставляет данные DATE, TIME и TIMESTAMP. Переменная mysql является допустимым дескриптором соединения.

MYSQL_TIME  ts;
MYSQL_BIND  bind[3];
MYSQL_STMT  *stmt;

strmov(query, "INSERT INTO test_table(date_field, time_field, \
       timestamp_field) VALUES(?,?,?");
stmt = mysql_stmt_init(mysql);
if (!stmt) {
   fprintf(stderr, " mysql_stmt_init(), out of memory\n");
   exit(0);
}
if (mysql_stmt_prepare(mysql, query, strlen(query))) {
   fprintf(stderr, "\n mysql_stmt_prepare(), INSERT failed");
   fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
   exit(0);
}
/* set up input buffers for all 3 parameters */
bind[0].buffer_type= MYSQL_TYPE_DATE;
bind[0].buffer= (char *)&ts;
bind[0].is_null= 0;
bind[0].length= 0;
...
bind[1]= bind[2]= bind[0];
...
mysql_stmt_bind_param(stmt, bind);
/* supply the data to be sent in the ts structure */
ts.year= 2002;
ts.month= 02;
ts.day= 03;
ts.hour= 10;
ts.minute= 45;
ts.second= 20;
mysql_stmt_execute(stmt);
..

25.8.20. Поддержка C API подготовленных запросов CALL

Этот раздел описывает поддержку готовых запросов в C API для хранимых процедур, выполненных, используя вызов CALL:

Хранимые процедуры, выполняемые через подготовленные запросы CALL, могут использоваться следующими способами:

Следующее обсуждение показывает, как использовать эти способности через C API для готовых запросов. Для использования подготовленных запросов CALL с запросами PREPARE и EXECUTE см. раздел 14.2.1. Синтаксис CALL.

Если приложение могло быть собрано или выполнено в контексте, где версия MySQL старше 5.5.3, подготовленный CALL не может обработать множественные наборы результатов и параметры OUT или INOUT:

Приложение, которое выполняет готовый запрос CALL, должно использовать цикл, который обрабатывает результаты и затем вызывает mysql_stmt_next_result() для определения наличия других наборов результатов. Результаты состоят из любых наборов результатов, произведенных хранимой процедурой, сопровождаемых значением окончательного статуса, которое указывает, закончилась ли процедура успешно.

Если процедура имеет параметры OUT или INOUT, набор результатов, предшествующий значению окончательного статуса, содержит их значения. Чтобы определить, содержит ли набор результатов значения параметра, проверьте установлен ли бит SERVER_PS_OUT_PARAMS в члене server_status обработчика соединения MYSQL:

mysql->server_status & SERVER_PS_OUT_PARAMS

Следующий пример использует готовый запрос CALL, чтобы выполнить хранимую процедуру, которая производит множественные наборы результатов, и предоставляет значения параметра посредством OUT и INOUT. Процедура берет параметры всех трех типов (IN, OUT и INOUT), выводит на экран их начальные значения, назначает новые значения, выводит на экран обновленные значения и завершается. Информация об ожидаемом возврате из процедуры поэтому состоит из множественных наборов результатов и окончательного статуса:

Код, чтобы выполнить процедуру:

MYSQL_STMT *stmt;
MYSQL_BIND ps_params[3];  /* input parameter buffers */
int        int_data[3];   /* input/output values */
my_bool    is_null[3];    /* output value nullability */
int        status;

/* set up stored procedure */
status = mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
test_error(mysql, status);
status = mysql_query(mysql, "CREATE PROCEDURE p1("
                     "  IN p_in INT, "
                     "  OUT p_out INT, "
                     "  INOUT p_inout INT) "
                     "BEGIN "
                     "  SELECT p_in, p_out, p_inout; "
                     "  SET p_in = 100, p_out = 200, p_inout = 300; "
                     "  SELECT p_in, p_out, p_inout; "
                     "END");
test_error(mysql, status);
/* initialize and prepare CALL statement with parameter placeholders */
stmt = mysql_stmt_init(mysql);
if (!stmt) {
   printf("Could not initialize statement\n");
   exit(1);
}
status = mysql_stmt_prepare(stmt, "CALL p1(?, ?, ?)", 16);
test_stmt_error(stmt, status);
/* initialize parameters: p_in, p_out, p_inout (all INT) */
memset(ps_params, 0, sizeof (ps_params));
ps_params[0].buffer_type = MYSQL_TYPE_LONG;
ps_params[0].buffer = (char *) &int_data[0];
ps_params[0].length = 0;
ps_params[0].is_null = 0;
ps_params[1].buffer_type = MYSQL_TYPE_LONG;
ps_params[1].buffer = (char *) &int_data[1];
ps_params[1].length = 0;
ps_params[1].is_null = 0;
ps_params[2].buffer_type = MYSQL_TYPE_LONG;
ps_params[2].buffer = (char *) &int_data[2];
ps_params[2].length = 0;
ps_params[2].is_null = 0;
/* bind parameters */
status = mysql_stmt_bind_param(stmt, ps_params);
test_stmt_error(stmt, status);
/* assign values to parameters and execute statement */
int_data[0]= 10;  /* p_in */
int_data[1]= 20;  /* p_out */
int_data[2]= 30;  /* p_inout */
status = mysql_stmt_execute(stmt);
test_stmt_error(stmt, status);
/* process results until there are no more */
do {
  int i;
  int num_fields; /* number of columns in result */
  MYSQL_FIELD *fields;  /* for result set metadata */
  MYSQL_BIND *rs_bind;  /* for output buffers */

  /* the column count is > 0 if there is a result set */
  /* 0 if the result is only the final status packet */
  num_fields = mysql_stmt_field_count(stmt);
  if (num_fields > 0) {
     /* there is a result set to fetch */
     printf("Number of columns in result: %d\n", (int) num_fields);
     /* what kind of result set is this? */
     printf("Data: ");
     if (mysql->server_status & SERVER_PS_OUT_PARAMS)
        printf("this result set contains OUT/INOUT parameters\n");
     else printf("this result set is produced by the procedure\n");
     MYSQL_RES *rs_metadata = mysql_stmt_result_metadata(stmt);
     test_stmt_error(stmt, rs_metadata == NULL);
     fields = mysql_fetch_fields(rs_metadata);
     rs_bind = (MYSQL_BIND *) malloc(sizeof (MYSQL_BIND) * num_fields);
     if (!rs_bind) {
        printf("Cannot allocate output buffers\n");
        exit(1);
     }
     memset(rs_bind, 0, sizeof (MYSQL_BIND) * num_fields);
     /* set up and bind result set output buffers */
     for (i = 0; i < num_fields; ++i) {
       rs_bind[i].buffer_type = fields[i].type;
       rs_bind[i].is_null = &is_null[i];
       switch (fields[i].type) {
         case MYSQL_TYPE_LONG:
           rs_bind[i].buffer = (char *) &(int_data[i]);
           rs_bind[i].buffer_length = sizeof (int_data);
           break;
         default:
           fprintf(stderr, "ERROR: unexpected type: %d.\n", fields[i].type);
           exit(1);
       }
     }
     status = mysql_stmt_bind_result(stmt, rs_bind);
     test_stmt_error(stmt, status);
     /* fetch and display result set rows */
     while (1) {
       status = mysql_stmt_fetch(stmt);
       if (status == 1 || status == MYSQL_NO_DATA) break;
       for (i = 0; i < num_fields; ++i) {
         switch (rs_bind[i].buffer_type) {
           case MYSQL_TYPE_LONG:
             if (*rs_bind[i].is_null) printf(" val[%d] = NULL;", i);
             else printf(" val[%d] = %ld;", i,
                         (long) *((int *) rs_bind[i].buffer));
             break;
           default:
             printf("  unexpected type (%d)\n", rs_bind[i].buffer_type);
         }
       }
       printf("\n");
     }
     mysql_free_result(rs_metadata); /* free metadata */
     free(rs_bind);    /* free output buffers */
  }
  else
  {
    /* no columns = final status packet */
    printf("End of procedure output\n");
  }
  /* more results? -1 = no, >0 = error, 0 = yes (keep looking) */
  status = mysql_stmt_next_result(stmt);
  if (status > 0) test_stmt_error(stmt, status);
} while (status == 0);
mysql_stmt_close(stmt);

Выполнение процедуры должно произвести следующий вывод:

Number of columns in result: 3
Data: this result set is produced by the procedure
      val[0] = 10; val[1] = NULL; val[2] = 30;
Number of columns in result: 3
Data: this result set is produced by the procedure
      val[0] = 100; val[1] = 200; val[2] = 300;
Number of columns in result: 2
Data: this result set contains OUT/INOUT parameters
      val[0] = 200; val[1] = 300;
End of procedure output

Код использует две служебных функции test_error() и test_stmt_error(), чтобы проверять на ошибки и печати диагностической информации, если ошибка произошла:

static void test_error(MYSQL *mysql, int status)
{
  if (status) {
     fprintf(stderr, "Error: %s (errno: %d)\n",
             mysql_error(mysql), mysql_errno(mysql));
     exit(1);
  }
}

static void test_stmt_error(MYSQL_STMT *stmt, int status)
{
  if (status) {
     fprintf(stderr, "Error: %s (errno: %d)\n",
             mysql_stmt_error(stmt), mysql_stmt_errno(stmt));
     exit(1);
  }
}

25.9. MySQL PHP API

Руководство MySQL PHP API теперь издан в автономной форме, не как часть полного руководства MySQL. См. MySQL и PHP.

25.10. MySQL Perl API

Perl DBI модуль обеспечивает интерфейс для доступа к базе данных. Вы можете написать скрипт DBI, который работает со многими различными механизмами базы данных без изменения. Чтобы использовать DBI с MySQL, установите следующее:

  1. Модуль DBI.

  2. Модуль DBD::mysql. Это модуль DataBase Driver (DBD) для Perl.
  3. Опционально модуль DBD для любого другого типа сервера базы данных, к которому Вы хотите получить доступ.

Perl DBI является рекомендуемым интерфейсом Perl. Это заменяет старый интерфейс mysqlperl, который нужно считать устаревшим.

Эти разделы содержат информацию об использовании Perl с MySQL и написании приложений MySQL на Perl:

Информация о DBI доступна в командной строке, онлайн или в печатной форме:

25.11. MySQL Python API

MySQLdb драйвер третьей фирмы, который оказывает поддержку MySQL для Python в соответствии с Python DB API version 2.0. Это может быть найдено на http://sourceforge.net/projects/mysql-python/.

Новый компонент MySQL Connector/Python предоставляет интерфейс к тому же самому Python API, встроен в MySQL Server и поддерживается Oracle. См. MySQL Connector/Python Developer Guide для деталей.

25.12. MySQL Ruby API

Два API доступны Ruby-программистам, разрабатывающим приложения MySQL:

25.12.1. MySQL/Ruby API

Модуль MySQL/Ruby обеспечивает доступ к базам данных MySQL, используя Ruby через libmysqlclient.

Для информации об установке модуля и функциях см. MySQL/Ruby.

25.12.2. Ruby/MySQL API

Модуль Ruby/MySQL обеспечивает доступ к базам данных MySQL, используя Ruby через интерфейс драйвера, используя протокол сети MySQL. Для информации об установке модуля и функциях см. Ruby/MySQL.

25.13. MySQL Tcl API

MySQLtcl простой API для того, чтобы получить доступ к серверу базы данных MySQL с помощью языка Tcl. Это может быть найдено на http://www.xdobry.de/mysqltcl/.

25.14. MySQL Eiffel Wrapper

Eiffel MySQL является интерфейсом к серверу базы данных MySQL, используя язык Eiffel, созданный Michael Ravits. Скачать можно на http://efsa.sourceforge.net/archive/ravits/mysql.htm.