Справочное руководство по MySQL версии 4.1.1-alpha. - 8 Интерфейсы для MySQL

Go to the first, previous, next, last section, table of contents.

# 8 Интерфейсы для MySQL

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

## 8.1 Интерфейс PHP API для MySQL

PHP представляет собой серверный язык программирования скриптов со встраиваемым кодом HTML, который может использоваться для создания динамических веб-страниц. Он содержит поддержку для доступа к нескольким базам данных, включая MySQL. PHP может запускаться как отдельная программа или компилироваться как модуль для использования с веб-сервером Apache.

Дистрибутив и документацию можно найти на веб-сайте PHP (http://www.php.net/).

### 8.1.1 Общие проблемы MySQL и PHP

- Ошибка: "Максимальное время исполнения превышено" ("Maximum Execution Time Exceeded"). Это ограничение PHP; откройте файл ``php3.ini'` и измените максимальное время исполнения с 30 секунд на более высокую величину, такую, какая вам необходима. Есть еще один неплохой способ - удвоить разрешенный объем оперативной памяти с 8 Мб до 16 Мб на скрипт.
- Ошибка: "Неисправимая ошибка: Вызов неподдерживаемой или неопределенной функции mysql_connect() в .." ("Fatal error: Call to unsupported or undefined function mysql_connect() in ..") Это означает, что ваша версия PHP не скомпилирована с поддержкой MySQL. Можно либо скомпилировать динамический модуль MySQL и загрузить его в PHP, либо перекомпилировать PHP со встроенной поддержкой MySQL. Это подробно описывается в руководстве по PHP.
- Ошибка: "неопределенная ссылка на `uncompress' (несжатый) " ("undefined reference to `uncompress'"). Это означает, что данная клиентская библиотека скомпилирована с поддержкой сжатого клиент-серверного протокола. Устранение этой проблемы заключается в добавлении `-lz` в конце при линковании с `-lmysqlclient`.

## 8.2 Интерфейс Perl API для MySQL

Этот раздел снабжает документами для работы с интерфейсом Perl `DBI`. Более ранний интерфейс назывался `mysqlperl`. В настоящее время интерфейс `DBI`/`DBD` является рекомендуемым интерфейсом Perl, так что `mysqlperl` здесь не документируется как устаревший.

### 8.2.1 `DBI` с помощью `DBD::mysql`

`DBI` представляет собой общий интерфейс для многих баз данных. Это означает, что можно написать скрипт, работающий со многими различными процессорами баз данных без изменения. При этом для каждого типа базы данных необходим определенный драйвер (DBD - это абревиатура DataBase Driver). Для MySQL этот драйвер называется `DBD::mysql`.

Для более подробной информации об интерфейсе Perl5 DBI, пожалуйста, посетите веб-страницу `DBI` и прочитайте документацию:

    http://dbi.perl.org/

Для более подробной информации об объектно ориентированном программировании (OOП), описанном в Perl5, смотрите веб-страницу Perl OOP:

    http://language.perl.com/info/documentation.html

Следует учитывать, что, если вы хотите использовать транзакции с Perl, то необходимо иметь модуль `Msql-Mysql-modules` версии 1.2216 или новее.

Рекомендуемый модуль для Perl: `DBD-mysql-2.1022` или новее.

Инструкции по установке поддержки Perl в MySQL даются в разделе See section 2.7 Замечания по установке Perl.

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

    shell> perldoc DBD/mysql
    shell> perldoc mysql

### 8.2.2 Интерфейс `DBI`

Унифицированные методы DBI

Метод | Описание
`connect` | Создает соединение с сервером
`disconnect` | Разрывает соединение с сервером
`prepare` | Готовит SQL-запрос к выполнению
`execute` | Выполняет приготовленный запрос
`do` | Готовит и выполняет запрос
`quote` | Заключает в символы цитирования строки или `BLOB`-значения, которые вы собираетесь внести
`fetchrow_array` | Возвращает следующую запись как массив
`fetchrow_arrayref` | Возвращает следующую запись как ссылку на массив
`fetchrow_hashref` | Возвращает следующую запись как ссылку на хеш
`fetchall_arrayref` | Возвращает всю информацию как массив массивов
`finish` | Завершает выражение и освобождает системные ресурсы
`rows` | Возвращает количество измененных/удаленных строк
`data_sources` | Возвращает массив, список баз данных, доступных на сервере
`ChopBlanks` | Определяет, будут ли методы `fetchrow_*` убирать начальные и оконечные пробелы
`NUM_OF_PARAMS` | Количество символов-заполнителей в приготовленном выражении
`NULLABLE` | Возвращает ссылку на массив значений, которые определяют, могут ли столбцы содержать значения `NULL`. Возможные значения для каждого элемента массива: 0 или пустая строка, если столбец не может быть `NULL`, 1 - если может, и 2, если статус `NULL` для столбца неизвестен
`trace` | Производит трассировку для отладки

Методы, определенные только для MySQL

Метод | Описание
`insrtid` | Значение `AUTO_INCREMENT`, которое было присвоено последним
`is_blob` | Какие столбцы имеют тип `BLOB`
`is_key` | Какие столбцы являются ключами
`is_num` | Какие столбцы имеют числовой тип
`is_pri_key` | Какие столбцы являются первичными ключами
`is_not_null` | Столбцы, которые НЕ МОГУТ иметь значение `NULL`. См. `NULLABLE`
`length` | Максимально допустимые размеры содержимого столбцов
`max_length` | Максимальные размеры столбцов, присутствующих в результате
`NAME` | Имена столбцов
`NUM_OF_FIELDS` | Количество полей, возвращенных в результате операции
`table` | Имена таблиц в результате
`type` | Типы всех столбцов

Более детально методы Perl DBI описаны в следующих разделах. Возвращаемые переменные:

`$dbh`
  Дескриптор базы данных
`$sth`
  Дескриптор выражения
`$rc`
  Код возврата (часто статус)
`$rv`
  Возвращенное значение (часто количество строк)

Унифицированные методы DBI

`connect($data_source, $username, $password)`
  Метод `connect` используется для подсоединения к источнику данных (СУБД). Строка `$data_source` должна начинаться с `DBI:имя драйвера:`. Примеры вызова connect с драйвером `DBD::mysql`:

      $dbh = DBI->connect("DBI:mysql:$database", $user, $password);
      $dbh = DBI->connect("DBI:mysql:$database:$hostname", $user,
      		$password);
      $dbh = DBI->connect("DBI:mysql:$database:$hostname:$port", $user,
      		$password);

  Если не определены имя пользователя либо пароль, `DBI` использует значения переменных окружения `DBI_USER` и `DBI_PASS`. Если не указано имя хоста, используется значение по умолчанию - `localhost`. Если не указан номер порта, также используется значение по умолчанию (3306). Начиная с `Msql-Mysql-modules` версии 1.2009, доступны следующие модификаторы `$data_source`:
  `mysql_read_default_file=file_name`
    Читать файл ``file_name'` как файл настроек. За более подробной информацией о файлах настройки обращайтесь к разделу See section 4.1.2 Файлы параметров ``my.cnf'`.
  `mysql_read_default_group=group_name`
    По умолчанию используется группа `[client]` файла настроек. Опцией `mysql_read_default_group`, группа по умолчанию устанавливается в `[group_name]`.
  `mysql_compression=1`
    Использовать сжатие при обмене клиента и сервера (MySQL версий 3.22.3 и выше).
  `mysql_socket=/path/to/socket`
    Указывает путь к Unix-сокету, который будет использоваться для соединения с сервером. (MySQL версии 3.21.15 и более поздние).
  Можно указывать не один модификатор, а несколько; при этом каждый должен предваряться точкой с запятой. Например, если вы не хотите явно указывать имя пользователя и пароль в программе, использующей `DBI`, можно внести эту информацию в файл ``~/.my.cnf'`, написав вызов `connect`. Это делается следующим образом:

      $dbh = DBI -> connect("DBI:mysql:$database",
      		  ";mysql_read_default_file=$ENV{HOME}/.my.cnf",
        		  $user, $password);

  Данный пример считает настройки из группы `[client]` файла ``~/.my.cnf'`. Чтобы выполнить те же действия, но с настройками, взятыми из группы `[perl]`, нужно использовать следующую форму записи:

      $dbh = DBI -> connect("DBI:mysql:$database",
      		  ";mysql_read_default_file=$ENV{HOME}/.my.cnf"
      		  . ";mysql_read_default_group=perl",
      		  $user, $password);

`disconnect`
  Метод disconnect разрывает соединение с базой данных. Это стоит делать перед выходом из программы. Пример:

      $rc = $dbh->disconnect;

`prepare($statement)`
  Подготавливает SQL-запрос `$statement` к исполнению сервером. Возвращает дескриптор выражения (`$sth`), который затем используется для вызова метода `execute`. Обычно работа с запросами типа `SELECT` (так же, как и аналогичными, такими как `SHOW`, `DESCRIBE`, `EXPLAIN`) сводится к вызову методов `prepare` и `execute`. Пример:

      $sth = $dbh -> prepare($statement)
      or die "Не  могу  подготовить $statement: $dbh -> errstr\n";

  Если вы хотите считывать большие результаты вашим клиентом, вы можете указать использование `mysql_use_result()` в Perl:

      my $sth = $dbh->prepare($statement { "mysql_use_result" => 1});

`execute`
  Метод `execute` выполняет приготовленный запрос. Если запрос не `SELECT`, метод возвращает количество строк, которые были подверглись воздействию запроса. Если таковых нет, `execute` возвращает `"0E0"`, что Perl интерпретирует как нуль, но воспринимает как значение ``истина'' (true). Если возникает ошибка, execute возвращает `undef`. Для запросов SELECT метод только инициирует выполнение запроса SQL-сервером и для получения данных необходимо использовать один из методов `fetch_*`. Пример:

      $rv = $sth -> execute or die "Не могу выполнить: $sth -> errstr";

`do($statement)`
  Метод `do` готовит SQL-запрос к выполнению, выполняет его и возвращает количество строк, подвергшихся воздействию. Если нет ни одной такой строки, как результат возвращается значение `"0E0"`, что Perl интерпретирует как нуль, но воспринимает как значение ``истина'' (true).. Этот метод обычно используется для выражений, не являющихся операторами `SELECT`, которые не могут быть подготовлены заранее (из-за ограничений драйвера) или же выполняются только один раз (операции вставки, удаления и т.д.). Например:

      $rv = $dbh->do($statement)
      or die "Не могу выполнить: $sth -> errstr";

  Обычно использование 'do' существенно быстрей (и предпочтительней) для запросов без параметров, чем пара `prepare`/`execute`.
`quote($string)`
  Метод `quote` используется для экранирования специальных символов в запросе символами экранирования, а также заключения данных в необходимые внешние символы цитирования (например кавычки). Пример:

      $sql = $dbh->quote($string)

`fetchrow_array`
  Этот метод выбирает очередную строку данных и возвращает ее как массив значений полей. Пример:

      while(@row = $sth -> fetchrow_array) {
      print qw($row[0]\t$row[1]\t$row[2]\n);
      }

`fetchrow_arrayref`
  Этот метод выбирает очередную строку данных и возвращает ссылку на массив значений полей. Пример:

      while($row_ref = $sth -> fetchrow_arrayref) {
      print qw($row_ref -> [0]\t$row_ref -> [1]\t$row_ref ->
      [2]\n);
      }

`fetchrow_hashref`
  Этот метод выбирает строку данных и возвращает ссылку на хеш, содержащий пары имя/значение. Данный метод намного менее эффективен, чем использование пописанных выше ссылок на массивы. Пример:

      while($hash_ref = $sth -> fetchrow_hashref) {
      print qw($hash_ref -> {firstname}\t$hash_ref ->
      {lastname}\t$hash_ref ->{title}\n);
      }

`fetchall_arrayref`
  Этот метод выдает все данные (все строки), получаемые как результат SQL-запроса. Он возвращает ссылку на массив ссылок на массивы отдельных строк. Соответственно, для обращения к этим данным нужно использовать вложенный цикл. Пример:

      my $table = $sth -> fetchall_arrayref
      or die "$sth -> errstr\n";
      my($i, $j);
      for $i ( 0 .. $#{$table}} ) {
      for $j ( 0 .. $#{$table -> [$i]} )  {
      print "$table -> [$i][$j]\t";
      }
      print "\n";
      }

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

      $rc = $sth -> finish;

`rows`
  Возвращает число измененных/удаленных последней командой (`UPDATE`, `DELETE` и т.д.) строк. Это обычно требуется после выполнения метода `execute` над запросами, не являющимися запросами `SELECT`. Например:

      $rv = $sth -> rows;

`NULLABLE`
  Возвращает ссылку на массив значений, которые указывают, может столбец принимать значения `NULL` или нет. Возможные значения для каждого элемента массива - это 0 или пустая строка, если столбец не может содержать значения `NULL`, 1 - если может и 2 - если статус столбца относительно значения `NULL` не определен. Например:

      $null_possible = $sth -> {NULLABLE};

`NUM_OF_FIELDS`
  Значение этого атрибута равно числу полей в результате запроса (`SELECT` или `SHOW FIELDS`). Его можно использовать его для проверки, возвращает ли запрос результат вообще: нулевое значение соответствует запросам типа `INSERT`, `DELETE`, `UPDATE` - т.е. всем, кроме `SELECT`. Например:

      $nr_of_fields = $sth -> {NUM_OF_FIELDS};

`data_sources($driver_name)`
  Этот метод возвращает массив с именами баз данных, доступных на локальном MySQL-сервере (на `localhost`). Пример:

      @dbs = DBI->data_sources("mysql");

`ChopBlanks`
  Этот атрибут определяет, будут ли методы `fetchrow_*` убирать начальные и оконечные пробелы из результатов. Пример:

      $sth -> {'ChopBlanks'} = 1;

`trace($trace_level)`
`trace($trace_level, $trace_filename)`
  Метод trace разрешает или запрещает трассировку. Если он вызывается как метод класса `DBI`, он влияет на разрешение трассировки всех дескрипторов. В случае же обращения к нему как к методу дескриптора запроса либо базы данных он разрешает/запрещает трассировку для этой базы данных или этого запроса (и всех будущих потомков). `$trace_level` указывает уровень детализации трассировочной информации, так установка `$trace_level` в 2 включает детализированную трассировку. Установка `$trace_level` в 0 запрещает трассировку. По умолчанию вывод трассировочной информации осуществляется на стандартное устройство вывода ошибок (`stderr`). Если указан параметр `$trace_filename`, его значение используется как имя файла, в который выводится трассировочная информация ВСЕХ дескрипторов, для которых разрешена трассировка. Пример:

      DBI->trace(2);                # трассировка всего
      DBI->trace(2,"/tmp/dbi.out"); # трассировка всего в /tmp/dbi.out
      $dth->trace(2);               # трассировка всех запросов к этой базе
      данных
      $sth->trace(2);               # трассировка этого запроса

  Трассировку `DBI` можно также включить при помощи переменной окружения `DBI_TRACE`. Присвоение числового значения эквивалентно вызову `DBI->trace(значение)`. Строковое значение (имя файла) эквивалентно вызову `DBI->trace(2,значение)`.

Методы, специфичные для MySQL

Описанные здесь методы специфичны для MySQL и не являются частью стандарта `DBI`. Сейчас считается, что часть из них использовать не стоит: `is_blob`, `is_key`, `is_num`, `is_pri_key`, `is_not_null`, `length`, `max_length` и `table`. Ниже указаны возможные стандартные альтернативы, если они существуют:

`insertid`
  Если вы используете специфичную для MySQL функцию `AUTO_INCREMENT`, здесь будут сохраняться автоматически увеличенные значения. Пример:

      $new_id = $sth->{insertid};

  В качестве альтернативы можно использовать `$dbh -> {'mysql_insertid'}`.
`is_blob`
  Возвращает ссылку на массив булевых значений; для каждого элемента массива значение ``истина'' указывает, что соответствующий столбец имеет тип `BLOB`. Например:

      $keys = $sth -> {is_blob};

`is_key`
  Возвращает ссылку на массив булевых значений; для каждого элемента массива значение ``истина'' указывает, что соответствующий столбец является ключом. Пример:

      $keys = $sth -> {is_key};

`is_num`
  Возвращает ссылку на массив булевых значений; для каждого элемента массива, значение ``истина'' указывает, что соответствующий столбец содержит числовые значения. Например:

      $nums = $sth -> {is_num};

`is_pri_key`
  Возвращает ссылку на массив булевых значений; для каждого элемента массива, значение ``истина'' указывает, что соответствующий столбец является первичным ключом. Пример:

      $pri_keys = $sth -> {is_pri_key};

`is_not_null`
  Возвращает ссылку на массив б булевых значений; для каждого элемента массива значение ``ложь'' указывает на то, что столбец может содержать значения `NULL`. Например:

      $not_nulls = $sth -> {is_not_null};

  `is_not_null` не рекомендуется к применению; предпочтительно использование `NULLABLE` (описан ранее), поскольку это стандартный для `DBI` метод.
`length`
`max_length`
  Каждый из этих методов возвращает ссылку на массив размеров столбцов. Массив, соответствующий `length`, содержит максимальные допустимые размеры каждого столбца (из описания таблицы). Массив `max_length` содержит максимальные размеры элементов, присутствующих в результирующей таблице. Например:

      $lengths = $sth -> {length};
      $max_lengths = $sth -> {max_length};

`NAME`
  Возвращает ссылку на массив имен столбцов. Например:

      $names = $sth -> {NAME};

`table`
  Возвращает ссылку на массив названий таблиц. Например:

      $tables = $sth -> {table};

`type`
  Возвращает ссылку на массив типов столбцов. Пример:

      $types = $sth -> {type};

### 8.2.3 Больше информации по `DBI`/`DBD`

Вы можете использовать команду `perldoc` для получения больше информации по `DBI`.

    perldoc DBI
    perldoc DBI::FAQ
    perldoc DBD::mysql

Конечно, вы можете использовать `pod2man`, `pod2html` и другие утилиты для трансляции в другие форматы.

Самая свежая информация по `DBI` живет на веб-сайте `DBI`: http://dbi.perl.org/.

## 8.3 Поддержка ODBC в MySQL

MySQL обеспечивает поддержку для ODBC посредством программы `MyODBC`. В этом разделе показано, как устанавливать и использовать `MyODBC`. Здесь также приведен список программ общего применения, о которых известно, что они работают с `MyODBC`.

### 8.3.1 Как установить MyODBC

`MyODBC` 2.50 представляет собой 32-разрядный драйвер ODBC спецификации уровня 0 (с возможностями уровней 1 и 2) для подсоединения совместимого с ODBC приложения к MySQL. `MyODBC` работает под Windows 9x/Me/NT/2000/XP и на большинстве платформ Unix.

`MyODBC` 3.51 это усовершенствованная версия ODBC со спецификационным уровнем 1 (полностью ядро API + уровень возможности 2).

`MyODBC` является свободно доступным. Самую свежую версию можно найти на http://www.mysql.com/downloads/api-myodbc.html.

Обратите внимание, что версии 2.50.х распространяются под `LGPL` лицензией, тогда как 3.51.х версии под лицензией `GPL`.

Если существуют проблемы с `MyODBC`, а программа также работает и с OLEDB, то следует попробовать работать с драйвером OLEDB.

Обычно установка `MyODBC` требуется только на компьютерах под Windows. Для Unix необходимость в `MyODBC` возникает только для программ, подобных ColdFusion, которые работают на Unix-машинах и используют ODBC для подключения к базам данных.

Для установки `MyODBC` на Unix-машину понадобится также программа управления ODBC. MyODBC, как известно, работает с большинством программ управления ODBC для Unix.

Для того чтобы установить `MyODBC` на Windows, необходимо загрузить соответствующий файл `MyODBC` ``.zip'`, распаковать его с помощью `WinZIP` или другой подобной программы и выполнить исполняемый файл ``SETUP.EXE'`.

При попытке установить `MyODBC` под Windows/NT/XP можно получить следующую ошибку:

    An error occurred while copying C:\WINDOWS\SYSTEM\MFC30.DLL. Restart
    Windows and try installing again (before running any applications which
    use  ODBC)

Проблема здесь заключается в том, что некоторая другая программа в это же время использует ODBC и из-за конструктивных особенностей Windows в данном случае может оказаться невозможным установить новый драйвер ODBC с помощью поставляемой Microsoft программы установки. В большинстве случаев можно продолжать установку, просто нажимая `Ignore` для копирования оставшихся файлов `MyODBC`, при этом заключительная установка должна работать. Если она не работает, то выход состоит в следующем: перезагрузите систему в безопасном режиме (safe mode) (для перехода в этот режим следует нажать F8 непосредственно перед тем, как компьютер начинает запускать Windows во время перезагрузки), установите `MyODBC` и перезагрузите Windows в обычном режиме.

- Чтобы установить подсоединение к Unix-компьютеру от Windows-компьютера с помощью приложения ODBC (которое само по себе не поддерживает MySQL), необходимо вначале установить MyODBC на Windows-машине.
- Данный пользователь и Windows-машина должны обладать привилегиями доступа к серверу MySQL на Unix-машине. Это устанавливается с помощью команды GRANT (see section 4.3.1 Синтаксис команд `GRANT` и `REVOKE`).
- Необходимо создать новую запись DSN ODBC следующим образом:
- Открыть Control Panel (Панель управления) на Windows-компьютере.
- Выполнить двойной щелчок на пиктограмме ODBC Data Sources 32-bit (Источники данных ODBC (32бит)).
- Щелкнуть на закладке User DSN (Пользовательский DSN).
- Щелкнуть на кнопке Add (Добавить).
- Выбрать MySQL в окне Create New Data Source (Создание нового источника данных) и щелкнуть на кнопке Finish (Готово).
- Откроется окно конфигурации драйвера MySQL по умолчанию (see section 8.3.2 Как заполнять различные поля в Администраторе ODBC).
- Теперь запустите свое приложение и выберите драйвер ODBC с помощью DSN, заданного вами в Администраторе источников данных ODBC.

Обратите внимание: существуют и другие возможности конфигурации в окне MySQL (трассировка, не подсказывать соединение и так далее), которые вы можете опробовать, если столкнетесь с какими-либо проблемами.

### 8.3.2 Как заполнять различные поля в Администраторе ODBC

Для Windows 95 существует три возможности задания имени сервера:

- Использовать IP-адрес сервера.
- Добавить файл \windows\lmhosts со следующей информацией:

      ip hostname

  Например:

      194.216.84.21 my_hostname

- Сконфигурировать ПК для использования DNS.

Пример заполнения при установке ODBC:

    Windows DSN name:   test
    Description:        This is my test database
    MySql Database:     test
    Server:             194.216.84.21
    User:               monty
    Password:           my_password
    Port:

Значением поля `Windows DSN name` может быть любое имя, уникальное для данной установки ODBC.

Не обязательно указывать значения для полей `Server`, `User`, `Password` или `Port` в окне установки ODBC. Однако если вы это сделали, данные величины в дальнейшем при установке соединения будут использованы как значения по умолчанию. Тогда же можно будет изменить эти значения.

Если номер порта не задан, то используется его значение по умолчанию (3306).

Если задается опция `Read options from C:\my.cnf`, то группы `client` и `odbc` будут читаться из файла ``C:\my.cnf'`. Можно применять все опции, используемые в `mysql_options()` (see section 8.4.3.39 `mysql_options()`).

### 8.3.3 Параметры подключения для MyODBC

Можно указать следующие параметры для `MyODBC` в разделе `[Servername]` файла ``ODBC.INI'` или через аргумент `InConnectionString` при вызове функции `SQLDriverConnect()`.

Параметр | Величина по умолчанию | Комментарий
user | ODBC (под Windows)@tab Имя пользователя, используемое для подключения к MySQL.
server | localhost | Имя хоста сервера MySQL.
database@tab | База данных по умолчанию.
option | 0 | Целое число, с помощью которого можно указать, как должен работать драйвер MyODBC (см. ниже).
port | 3306 | Используемый порт TCP/IP, если значением `server` не является `localhost`.
stmt |  | Команда, которая будет выполняться при подключении к MySQL.
password@tab | Пароль для комбинации `server user`.
socket |  | Сокет или канал Windows для подключения.

Аргумент ``option'' используется для указания `MyODBC`, что данный клиент не на 100% соответствует ODBC. Под Windows обычно устанавливается флаг опций путем переключения различных опций в окне данного соединения, но можно также установить это в аргументе ``option''. Следующие опции перечислены в том же порядке, в котором они перечислены в окне подключения `MyODBC`:

Бит | Описание
1 | Данный клиент не может отследить, что драйвер `MyODBC` возвращает реальную ширину столбца.
2 | Данный клиент не может отследить, что драйвер `MyODBC` возвращает реальную величину подвергшихся воздействию строк. Если этот флаг установлен, то взамен MySQL возвращает ``найденные строки''. Необходима версия MySQL 3.21.14 или более новая, чтобы эта опция работала.
4 | Создает журнал отладки в c:\myodbc.log. Это то же самое, что задать `MYSQL_DEBUG=d:t:O,c::\myodbc.log` в ``AUTOEXEC.BAT'`
8 | Не устанавливать никаких пакетных ограничений для результатов и параметров.
16 | Не выводить подсказки для вопросов, даже если драйвер захотел бы предложить это
32 | Имитировать драйвер ODBC 1.0 в определенной ситуации.
64 | Игнорировать использование имени базы данных в `database.table.column`.
128 | Заставляет использовать указатели менеджера ODBC (экспериментальная).
256 | Отключить использование расширенной выборки (экспериментальная).
512 | Заполнить поля `CHAR` до полной длины столбца.
1024 | Функция SQLDescribeCol() будет возвращать полностью уточненные имена столбцов
2048 | Использовать сжатие в клиент-серверном протоколе
4096 | Предписывает серверу игнорировать пробел после имени функции и перед ``('` (необходимо для PowerBuilder). Это сделает имена всех функций ключевыми словами!
8192 | Соединяет с именованными каналами сервер `mysqld`, работающий под NT.
16384 | Изменяет тип столбцов `LONGLONG` на `INT` (некоторые приложения не могут обрабатывать LONGLONG).
32768 | Возвращает параметр `user` как `Table_qualifier` и `Table_owner` из SQL-таблиц (экспериментальная)
65536 | Читает параметры из групп `client` и `odbc` из файла ``my.cnf'`
131072 | Добавляет некоторые дополнительные проверки безопасности (не должно понадобиться, но...)

Если необходимо иметь много опций, следует добавить вышеуказанные флаги! Например, установка опции в 12 (4+8) дает отладку без ограничений пакетов!

По умолчанию ``MYODBC.DLL'` компилируется для оптимальной производительности. Если необходимо отладить `MyODBC` (например, включить трассировку), следует вместо этого использовать ``MYODBCD.DLL'`. Для установки этого файла следует скопировать ``MYODBCD.DLL'` поверх установленного файла ``MYODBC.DLL'`.

### 8.3.4 Как сообщать о проблемах с MyODBC

Драйвер `MyODBC` был протестирован с Access, Admndemo.exe, C++-Builder, Borland Builder 4, Centura Team Developer (первоначально Gupta SQL/Windows), ColdFusion (под Solaris и NT с пакетом обновлений svc pack 5), Crystal Reports, DataJunction, Delphi, ERwin, Excel, iHTML, FileMaker Pro, FoxPro, Notes 4.5/4.6, SBSS, Perl DBD-ODBC, Paradox, Powerbuilder, 32-разрядным Powerdesigner, VC++ и Visual Basic.

Если вам известны какие- либо другие приложения, работающие с MyODBC, пожалуйста, пошлите сообщение об этом по адресу myodbc@lists.mysql.com!

При работе с некоторыми программами можно получить ошибку вроде: `Another user has modifies the record that you have modified`.

В большинстве случаев эту проблему можно устранить одним из следующих способов:

- Добавить первичный ключ для данной таблицы, если он еще не создан.
- Добавить столбец `TIMESTAMP`, если он еще не создан.
- Использовать поля только с числами с плавающей запятой двойной точности. Некоторые программы могут не срабатывать при сравнении чисел с плавающей запятой одинарной точности.

Если перечисленные выше способы не помогают, необходимо сделать трассировочный файл `MyODBC` и попробовать определить, в чем дело.

### 8.3.5 Программы, работающие с MyODBC

Большинство программ должно работать с `MyODBC`, но для каждой из перечисленных ниже мы либо провели тестирование сами, либо получили подтверждение от пользователей, что она действительно работает:

Программа
  Комментарий
Access
  Чтобы заставить Access работать:
  - При использовании Access 2000 необходимо установить самую последнюю версию (2.6 или выше) Microsoft MDAC (`Microsoft Data Access Components`), которую можно найти на http://www.microsoft.com/data/. Это позволит устранить ошибку в Access, которая проявляется в том, что при экспорте данных в MySQL не указываются имена таблиц и столбцов. Еще один способ обойти эту ошибку заключается в модернизации `MyODBC` до версии 2.50.33 и MySQL до версии 3.23.x - оба апгрейда вместе обеспечивают обход данной ошибки! Необходимо также получить и использовать Microsoft Jet 4.0 Service Pack 5 (SP5), который можно найти на http://support.microsoft.com/support/kb/articles/Q 239/1/14.ASP. Это позволит исключить некоторые случаи, когда столбцы в Access отмечаются как `#deleted#`. Следует учитывать, что при использовании версии MySQL 3.22 необходимо применять патч для MDAC и использовать MyODBC 2.50.32 или 2.50.34 и выше, чтобы обойти эту проблему.
  - Для всех версий Access необходимо включить для MyODBC флаг опции `Return matching rows`. Для Access 2.0 следует дополнительно включить Simulate ODBC 1.0.
  - Все таблицы, в которых вы хотите иметь возможность обновления, должны содержать столбец типа `TIMESTAMP` для временных меток. Для максимальной переносимости рекомендуется `TIMESTAMP(14)` или просто `TIMESTAMP` вместо других вариантов `TIMESTAMP(X)`.
  - Таблица должна иметь первичный ключ. Если не имеет, то новые или обновленные строки могут выводиться как `#DELETED#`.
  - Используйте поля с числами с плавающей запятой только двойной точности (типа `DOUBLE`). Access отказывается работать при сравнении чисел с плавающей запятой одинарной точности. Проявляется это обычно в том, что новые или обновленные строки могут выводиться как `#DELETED#` или в том, что вы не можете найти или обновить строки.
  - При связывании через MyODBC таблицы, один из столбцов которой имеет тип `BIGINT`, результат будет выводиться как `#DELETED#`. Обходное решение заключается в следующем:
    - Добавьте еще один пустой столбец с `TIMESTAMP` в качестве типа данных, предпочтительно `TIMESTAMP(14)`.
    - Проверьте `Change BIGINT columns to INT` в диалоговом окне опций подключения в Администраторе источников данных ODBC DSN
    - Удалите данную табличную связь из Access и создайте ее вновь.
    После этого старые записи все равно будут представлены как `#DELETED#`, а заново добавленные/обновленные записи будут уже выводиться правильно.
  - Если после добавления столбца `TIMESTAMP` все еще появляется ошибка `Another user has changed your data`, то, возможно, поможет следующий трюк. Не используйте режим работы ``Таблица''. Вместо этого создайте форму с желаемыми полями и используйте режим работы ``Форма''. Следует установить свойство `DefaultValue` для столбца `TIMESTAMP` в `NOW()`. Возможно, было бы неплохо убрать столбец `TIMESTAMP` из поля зрения, чтобы не смущать пользователей.
  - В некоторых случаях Access может создавать недопустимые запросы SQL, которые MySQL не может понять. Это можно устранить путем выбора в меню Access опции `Query|SQLSpecific|Pass-Through`.
  - Access под NT будет сообщать о столбцах `BLOB` как об объектах OLE. Если вместо этого вы хотите иметь столбцы `MEMO`, то необходимо изменить тип столбца на `TEXT` с помощью `ALTER TABLE`.
  - Access не всегда может правильно обработать столбцы типа `DATE`. Если с ними возникают проблемы, следует изменить тип этих столбцов на `DATETIME`.
  - Если Access содержит столбец, определенный как `BYTE`, то Access будет пытаться экспортировать его как `TINYINT` вместо `TINYINT UNSIGNED`. Это будет вызывать проблемы, если величины в данном столбце превышают 127!
ADO
  При написании программ с привлечением интерфейса ADO API и `MyODBC` необходимо обратить внимание на некоторые исходные свойства, которые не поддерживаются сервером MySQL. Например, использование свойства `CursorLocation` как `adUseServer` будет возвращать для свойства `RecordCount` результат -1. Чтобы получить правильную величину, необходимо установить данное свойство в `adUseClient`, как показано в коде VB ниже:

      Dim myconn As New ADODB.Connection
      Dim myrs As New Recordset
      Dim mySQL As String
      Dim myrows As Long

      myconn.Open "DSN=MyODBCsample"
      mySQL = "SELECT * from user"
      myrs.Source = mySQL
      Set myrs.ActiveConnection = myconn
      myrs.CursorLocation = adUseClient
      myrs.Open
      myrows = myrs.RecordCount

      myrs.Close
      myconn.Close

  Еще один обходной путь состоит в том, чтобы для такого запроса использовать команду `SELECT COUNT(*)`, чтобы получить правильное количество строк.
Активные серверные страницы (ASP)
  Необходимо использовать флаг опции `Return matching rows`.
BDE-приложения
  Чтобы заставить их работать, следует установить флаги опций `Don't optimize column widths` и `Return matching rows`.
Borland Builder 4
  При запуске запроса можно использовать свойство `Active` или метод `Open`. Следует учитывать, что `Active` будет начинать работу при автоматической выдаче запроса `SELECT * FROM ...`, что может оказаться не так уж и хорошо для больших таблиц!
ColdFusion (Под Unix)
  Приведенные далее сведения взяты из документации по ColdFusion. Для применения драйвера unixODBC с источником данных `MyODBC` следует использовать следующую информацию. Корпорация Allaire подтвердила, что версия MyODBC 2.50.26 работает с версией MySQL 3.22.27 и ColdFusion для Linux (любая более новая версия также должна работать). Драйвер `MyODBC` можно загрузить с http://www.mysql.com/downloads/api-myodbc.html В версии ColdFusion 4.5.1 можно использовать Администратор источников данных ColdFusion для добавления источника данных MySQL. Однако данный драйвер не включен в версию ColdFusion 4.5.1. Чтобы драйвер MySQL появился в выпадающем списке источников данных ODBC, необходимо создать драйвер `MyODBC` и скопировать его в каталог ``/opt/coldfusion/lib/libmyodbc.so'`. Каталог ``Contrib'` содержит программу ``mydsn-xxx.zip'`, которая позволяет создавать и удалять файл реестра DSN для драйвера `MyODBC` для приложений Coldfusion.
DataJunction
  Необходимо изменить эту программу для вывода `VARCHAR` вместо `ENUM`, поскольку экспорт `ENUM` происходит таким образом, что вызывает неприятности в MySQL.
Excel
  Работает. Несколько замечаний:
  - Если существуют проблемы с датами, попробуйте выбирать их как строки, используя функцию `CONCAT()`. Например:

        select CONCAT(rise_time), CONCAT(set_time)
        	from sunrise_sunset;

    Величины, извлеченные как строки этим способом, должны корректно распознаваться программой Excel97 как значения времени. Назначение функции `CONCAT()` в этом примере состоит в том, чтобы ``обмануть'' ODBC, заставив интерпретировать столбец как столбец ``строкового типа''. Без функции `CONCAT()` ODBC будет считать, что это столбец временного типа, и Excel не распознает его. Следует заметить, что это является ошибкой Excel, поскольку он автоматически преобразует строку в значения времени. Это замечательно если источником является текстовый файл, но это глупо, когда источником является подключение ODBC, дающее точные типы данных для каждого столбца.
Word
  Для извлечения данных из MySQL в документы Word/Excel следует использовать драйвер `MyODBC` и помощь встроенной программы Microsoft Query. Для создания, например, базы данных `db` с таблицей, содержащей 2 столбца с текстом, необходимо выполнить следующие действия:
  - Вставьте строки, используя командную строку клиента `mysql`.
  - Создайте файл DSN, используя менеджер ODBC, например, my для созданной выше базы данных `db`.
  - Откройте приложение Word.
  - Создайте новый пустой документ.
  - Используя панель инструментов вызванной базы данных, нажмите кнопку Insert database.
  - Нажмите кнопку Get Data.
  - В окне Get Data справа нажмите кнопку Ms Query.
  - В окне Ms Query создайте новый источник данных, используя файл DSN my.
  - Выберите новый запрос.
  - Выберите желаемый столбец.
  - Создайте фильтр (при желании).
  - Создайте сортировку (при желании).
  - Выберите Return Data to Microsoft Word.
  - Нажмите кнопку Finish.
  - Нажмите Insert data и выбирайте записи.
  - Нажмите Ok. Вы увидите выбранные строки в своем документе в Word.
odbcadmin
  Тестовая программа для ODBC.
Delphi
  Необходимо использовать версию BDE 3.2 или более новую. Установите поле опции `Don't optimize column width` при подключении к MySQL. Кроме того, ниже приводится потенциально полезный код Delphi, который устанавливает вхождения для драйвера MyODBC как в ODBC, так и в BDE. (Запись в BDE требует наличия редактора псевдонимов BDE Alias Editor, который доступен бесплатно на Delphi Super Page. Спасибо за это Брайену Брантону (Bryan Brunton bryan@flesherfab.com)):

      fReg:= TRegistry.Create;
      fReg.OpenKey('\Software\ODBC\ODBC.INI\DocumentsFab', True);
      fReg.WriteString('Database', 'Documents');
      fReg.WriteString('Description', ' ');
      fReg.WriteString('Driver', 'C:\WINNT\System32\myodbc.dll');
      fReg.WriteString('Flag', '1');
      fReg.WriteString('Password', '');
      fReg.WriteString('Port', ' ');
      fReg.WriteString('Server', 'xmark');
      fReg.WriteString('User', 'winuser');
      fReg.OpenKey('\Software\ODBC\ODBC.INI\ODBC Data Sources', True);
      fReg.WriteString('DocumentsFab', 'MySQL');
      fReg.CloseKey;
      fReg.Free;

      Memo1.Lines.Add('DATABASE NAME=');
      Memo1.Lines.Add('USER NAME=');
      Memo1.Lines.Add('ODBC DSN=DocumentsFab');
      Memo1.Lines.Add('OPEN MODE=READ/WRITE');
      Memo1.Lines.Add('BATCH COUNT=200');
      Memo1.Lines.Add('LANGDRIVER=');
      Memo1.Lines.Add('MAX ROWS=-1');
      Memo1.Lines.Add('SCHEMA CACHE DIR=');
      Memo1.Lines.Add('SCHEMA CACHE SIZE=8');
      Memo1.Lines.Add('SCHEMA CACHE TIME=-1');
      Memo1.Lines.Add('SQLPASSTHRU MODE=SHARED AUTOCOMMIT');
      Memo1.Lines.Add('SQLQRYMODE=');
      Memo1.Lines.Add('ENABLE SCHEMA CACHE=FALSE');
      Memo1.Lines.Add('ENABLE BCD=FALSE');
      Memo1.Lines.Add('ROWSET SIZE=20');
      Memo1.Lines.Add('BLOBS TO CACHE=64');
      Memo1.Lines.Add('BLOB SIZE=32');
      AliasEditor.Add('DocumentsFab','MySQL',Memo1.Lines);

C++ Builder
  Проведено тестирование с версией BDE 3.0. Единственная обнаруженная проблема состоит в том, что при изменениях схемы таблиц не обновляются поля запросов. Хотя BDE не распознает первичных ключей, а только индекс `PRIMARY`, тем не менее, это не было проблемой.
Vision
  Необходимо использовать флаг опции `Return matching rows`.
Visual Basic
  Чтобы обеспечить возможность обновить таблицу, для нее необходимо определить первичный ключ. Visual Basic с ADO не обрабатывает больших целых чисел. Это означает, что некоторые запросы вроде `SHOW PROCESSLIST` не будут работать правильно. Для устранения данной проблемы нужно добавить опцию `OPTION=16384` в строке подключения ODBC или установить опцию `Change BIGINT columns to INT` в окне подключения `MyODBC`. Можно также установить опцию `Return matching rows`.
VisualInterDev
  Если возникает ошибка `[Microsoft][ODBC Driver Manager] Driver does not support this parameter`, то ее причина может заключаться в том, что результат содержит данные типа `BIGINT`. Попробуйте установить опцию `Change BIGINT columns to INT` в окне подключения `MyODBC`.
Visual Objects
  Необходимо использовать флаг опции `Don't optimize column widths`.

### 8.3.6 Как получить значение столбца AUTO_INCREMENT в ODBC

Существует распространенная проблема, заключающаяся в том, как получить значение автоматически сгенерированного `ID` из `INSERT`. С помощью ODBC можно сделать что-то наподобие следующего (предполагается, что auto представляет собой поле `AUTO_INCREMENT` ):

    INSERT INTO foo (auto,text) VALUES(NULL,'text');
    SELECT LAST_INSERT_ID();

Или, если вы просто собираетесь вставить данный `ID` в другую таблицу, то можно сделать так:

    INSERT INTO foo (auto,text) VALUES(NULL,'text');
    INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text');

See section 8.4.6.3 Как получить уникальный идентификатор для последней внесенной строки?.

Для некоторых приложений ODBC (по крайней мере, для Delphi и Access), чтобы найти недавно вставленную строку, можно использовать следующий запрос:

    SELECT * FROM tbl_name WHERE auto IS NULL;

### 8.3.7 Составление отчетов о проблемах с MyODBC

Если встречаются трудности с применением `MyODBC`, то следует начинать с получения системного журнала менеджера ODBC (журнал, получаемый при затребовании записей в Администраторе ODBC) и журнала `MyODBC`.

Чтобы получить журнал `MyODBC`, необходимо выполнить следующие действия:

1. Убедитесь, что вы используете ``myodbcd.dll'`, а не ``myodbc.dll'`. Наиболее простой способ - получить файл ``myodbcd.dll'` из дистрибутива `MyODBC` и скопировать его поверх файла ``myodbc.dll'`, который должен находиться в вашем каталоге ``C:\windows\system32'` или ``C:\winnt\system32'`. Однако после окончания тестирования целесообразно восстановить старый файл ``myodbc.dll'`, поскольку он намного быстрее, чем ``myodbcd.dll'`.
2. Включите опцию `Trace` `MyODBC` в окне подключения/конфигурации `MyODBC`. Информация будет записываться в файл ``C:\myodbc.log'`. Если опция трассировки не запоминается при возвращении к предыдущему окну, то это означает, что сейчас драйвер ``myodbcd.dll'` не используется (см. пункт выше).
3. Запустите свое приложение и попытайтесь получить отказ в работе.

Проверьте трассировочный файл `MyODBC`, что бы попытаться выяснить, в чем дело. Можно также найти сделанные вами запросы в файле ``myodbc.log'` - поищите в нем строку `>mysql_real_query`.

Попробуйте также выполнить дублирование этих запросов с помощью монитора `mysql` или `admndemo`, чтобы определить, где возникает ошибка - в MyODBC или в MySQL.

Если вы обнаружите какую-либо ошибку, то присылайте, пожалуйста, только строки, имеющие отношение к ней (максимум 40 строк), по адресу myodbc@lists.mysql.com. Просьба никогда не присылать полностью весь системный журнал MyODBC или ODBC!

Если у вас нет возможности определить, что именно у вас не так, остается последняя возможность - создать архив (tar или zip), содержащий трассировочный файл MyODBC, системный журнал ODBC и файл README с описанием своей проблемы. Вы можете послать это по адресу ftp://support.mysql.com/pub/mysql/secret/. В MySQL AB только мы будем иметь доступ к присланным вами файлам. Гарантируем, что с ними мы будем обращаться очень осторожно!

Если вы можете создать программу для демонстрации данной проблемы, присылайте, пожалуйста, и ее тоже!

Если эта программа работает с некоторыми другими серверами SQL, следует сделать системный журнал ODBC, где вы делаете в точности то же самое в другом сервере SQL.

Помните, что чем больше информации вы нам предоставите, тем больше вероятность, что мы сможем решить данную проблему!

## 8.4 Интерфейс C для MySQL

Исходный код программного интерфейса (API) C распространяется вместе с MySQL. Он включает в себя библиотеку `mysqlclient` и обеспечивает возможность доступа к базе данных программам на С.

Многие клиенты исходного дистрибутива MySQL написаны на C. Они являются хорошими примерами для демонстрации использования интерфейса C. Их можно найти их в каталоге `clients` исходного дистрибутива MySQL.

Большинство других клиентских интерфейсов (за исключением Java) для соединения с сервером MySQL используют библиотеку `mysqlclient`. Это означает, что, например, можно извлечь определенную выгоду, используя те же переменные окружения, что и в других клиентских программах, поскольку на них есть ссылки из библиотеки (see section 4.8 Клиентские сценарии и утилиты MySQL, где приведен список этих переменных).

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

Буфер связи должен быть достаточно большим, чтобы вмещать целую SQL-команду (для потока клиент-сервер) и целую строку возвращенных данных (для потока сервер-клиент). Буфер связи для каждого из потоков динамически увеличивается до максимального значения, чтобы обработать любой запрос или строку. Например, для данных типа `BLOB` объемом до 16 Mб необходим предел буфера связи по меньшей мере в 16 Mб (как для сервера, так и для клиента). Максимальное значение по умолчанию для клиента составляет 16 Mб, а для сервера максимум по умолчанию равен 1Mб. Можно увеличить этот объем, изменив величину параметра `max_allowed_packet` при запуске сервера (see section 5.5.2 Настройка параметров сервера).

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

Программирование с учетом потоков описано в разделе See section 8.4.8 Как создать клиентскую программу с потоками. При создании автономного приложения, включающего и "сервер", и "клиент" в одной и той же программе (и не взаимодействующего с внешним сервером MySQL), обращайтесь к разделу See section 8.4.9 libmysqld, встраиваемая библиотека сервера MySQL.

### 8.4.1 Типы данных C API

`MYSQL`
  Данная структура представляет дескриптор соединения с базой данных. Используется почти во всех функциях MySQL.
`MYSQL_RES`
  Эта структура содержит результат запроса, возвратившего строки (`SELECT`, `SHOW`, `DESCRIBE`, `EXPLAIN`). Возвращенная из запроса информация далее в этом разделе называется результирующим набором данных.
`MYSQL_ROW`
  Является ``типобезопасным'' представлением данных одной строки. В настоящее время этот тип реализован как массив строк с фиксированным количеством байтов (их нельзя трактовать как строки с нулевым символом в конце, если величины полей могут содержать двоичные данные, поскольку они могут содержать ноль байтов). Строки можно получить вызовом функции `mysql_fetch_row()`.
`MYSQL_FIELD`
  Данная структура содержит информацию об отдельном поле таблицы: имя поля, тип и его размер. Элементы данной структуры детально описаны в этом разделе ниже. Для каждого поля можно получить структуру `MYSQL_FIELD`, последовательно вызывая функцию `mysql_fetch_field()`. Величины полей не являются частью данной структуры, они содержатся в структуре `MYSQL_ROW`.
`MYSQL_FIELD_OFFSET`
  ``Типобезопасное'' представление позиции поля в списке полей MySQL. (используется функцией `mysql_field_seek()`). Позиции представляют собой номера полей внутри строки, причем нумерация начинается с нуля.
`my_ulonglong`
  Данный тип используется для возврата количества строк, а также в функциях `mysql_affected_rows()`, `mysql_num_rows()` и `mysql_insert_id()`. Этот тип обеспечивает диапазон изменений величин от 0 до 1.84e19. Может не работать в некоторых системах при выводе величины типа `my_ulonglong`. Для вывода подобной величины следует преобразовать ее в тип `unsigned long` и использовать формат `%lu`. Пример:

      printf (Количество  строк: %lu\n", (unsigned long) mysql_num_rows(result));

Структура `MYSQL_FIELD` содержит следующие перечисленные ниже элементы:

`char * name`
  Имя данного поля, заданное строкой с нулевым символом в конце.
`char * table`
  Имя таблицы, содержащей это поле, если оно невычисляемое. Для полей, получаемых в результате вычислений, величина `table` представляет собой пустую строку.
`char * def`
  Значение по умолчанию этого поля, заданное строкой с нулевым символом в конце. Задается только при использовании функции `mysql_list_fields()`.
`enum enum_field_types type`
  Тип данного поля. Величина `type` может быть одной из следующих:

  Тип величины | Описание типа
  `FIELD_TYPE_TINY` | Поле `TINYINT`
  `FIELD_TYPE_SHORT` | Поле `SMALLINT`
  `FIELD_TYPE_LONG` | Поле `INTEGER`
  `FIELD_TYPE_INT24` | Поле `MEDIUMINT`
  `FIELD_TYPE_LONGLONG` | Поле `BIGINT`
  `FIELD_TYPE_DECIMAL` | Поле `DECIMAL` или `NUMERIC`
  `FIELD_TYPE_FLOAT` | Поле `FLOAT`
  `FIELD_TYPE_DOUBLE` | Поле `DOUBLE` или `REAL`
  `FIELD_TYPE_TIMESTAMP` | Поле `TIMESTAMP`
  `FIELD_TYPE_DATE` | Поле `DATE`
  `FIELD_TYPE_TIME` | Поле `TIME`
  `FIELD_TYPE_DATETIME` | Поле `DATETIME`
  `FIELD_TYPE_YEAR` | Поле `YEAR`
  `FIELD_TYPE_STRING` | Строка поля (`CHAR` или `VARCHAR`)
  `FIELD_TYPE_BLOB` | `BLOB` или `TEXT` поле (используется `max_length` для определения максимальной длинны)
  `FIELD_TYPE_SET` | Поле типа `SET`
  `FIELD_TYPE_ENUM` | Поле типа `ENUM`
  `FIELD_TYPE_NULL` | Поле типа `NULL`
  `FIELD_TYPE_CHAR` | Не рекомендуется; лучше использовать `FIELD_TYPE_TINY`

  Можно использовать макрос `IS_NUM()` для проверки, является ли тип поля числовым. В макросе `IS_NUM()` следует указать величину `type` и, если поле имеет числовой тип, будет возвращено значение `TRUE`:

      if (IS_NUM(field->type))
         printf("Field is numeric\n");

`unsigned int length`
  Размер данного поля в том виде, в каком он указан в определении таблицы.
`unsigned int max_length`
  Максимальный размер данного поля в результирующем наборе данных (длина самой большой величины поля для строк в текущем результирующем наборе данных). При использовании `mysql_store_result()` или `mysql_list_fields()` данная переменная содержит максимальную длину для данного поля. При использовании `mysql_use_result()` значение этой переменной равно нулю.
`unsigned int flags`
  Различные двоичные флаги для данного поля. Величина `flags` может иметь ноль или больше двоичных значений следующего набора флагов:

  Значение флага | описание флага
  `NOT_NULL_FLAG` | Поле не может содержать значение `NULL`
  `PRI_KEY_FLAG` | Поле является частью первичного ключа
  `UNIQUE_KEY_FLAG` | Поле является частью уникального ключа
  `MULTIPLE_KEY_FLAG` | Поле является частью не уникального ключа
  `UNSIGNED_FLAG` | Поле имеет атрибут `UNSIGNED`
  `ZEROFILL_FLAG` | Поле имеет атрибут `ZEROFILL`
  `BINARY_FLAG` | Поле имеет атрибут `BINARY`
  `AUTO_INCREMENT_FLAG` | Поле имеет атрибут `AUTO_INCREMENT`
  `ENUM_FLAG` | Поле имеет тип `ENUM` (не рекомендуется)
  `SET_FLAG` | Поле имеет тип `SET` (не рекомендуется)
  `BLOB_FLAG` | Поле имеет тип `BLOB` или `TEXT` (не рекомендуется)
  `TIMESTAMP_FLAG` | Поле имеет тип `TIMESTAMP` (не рекомендуется)

  Использование флагов `BLOB_FLAG`, `ENUM_FLAG`, `SET_FLAG` и `TIMESTAMP_FLAG` не рекомендуется, поскольку они указывают скорее тип поля, чем атрибут этого типа. Вместо этого более предпочтительно определять тип поля описанным выше способом `field->type` в отношении полей `FIELD_TYPE_BLOB`, `FIELD_TYPE_ENUM`, `FIELD_TYPE_SET` или `FIELD_TYPE_TIMESTAMP`. Следующий пример иллюстрирует типичное использование величины `flags`:

      if (field->flags & NOT_NULL_FLAG)
         printf("Field can't be null\n");

  Можно использовать следующие возможности макросов для определения булевого значения величины `flags`:

  Статус флага | Описание
  `IS_NOT_NULL(flags)` | Возвращает TRUE, если данное поле определено как `NOT NULL`
  `IS_PRI_KEY(flags)` | Возвращает TRUE, если данное поле является первичным ключом
  `IS_BLOB(flags)` | Возвращает TRUE, если данное поле имеет тип `BLOB` или `TEXT` (не рекомендуется; более предпочтительно `field->type`)

`unsigned int decimals`
  Возвращает число десятичных знаков для числовых полей.

### 8.4.2 Обзор функций интерфейса C

В приведенной ниже таблице перечислены доступные в интерфейсе C функции. Более детально они описаны в следующем разделе (see section 8.4.3 Описание функций интерфейса C).

Функция | Описание
mysql_affected_rows() | Возвращает количество строк, измененных/удаленных/вставленных последним запросом `UPDATE`, `DELETE` или `INSERT`.
mysql_change_user() | Переключает пользователя и базу данных для открытого соединения.
mysql_character_set_name() | Возвращает название кодировки, установленной для данного соединения.
mysql_close() | Закрывает соединение с сервером.
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_seek() | Устанавливает курсор столбцов на заданный столбец.
mysql_field_count() | Возвращает количество столбцов в результате для последнего запроса.
mysql_field_tell() | Возвращает значение положения курсора поля для последнего вызова `mysql_fetch_field()`.
mysql_free_result() | Освобождает память, использованную для результирующего набора.
mysql_get_client_info() | Возвращает информацию о версии клиента.
mysql_get_host_info() | Возвращает строку, описывающую параметры текущего соединения.
`mysql_get_server_version()` | Возвращает номер версии сервера как целое число (новое с 4.1)
mysql_get_proto_info() | Возвращает версию протокола, используемого для данного соединения.
mysql_get_server_info() | Возвращает номер версии сервера баз данных.
mysql_info() | Возвращает информацию о последнем выполненном запросе.
mysql_init() | Выделяет или инициализирует какую-либо структуру MYSQL.
mysql_insert_id() | Возвращает идентификатор, сгенерированный для столбца `AUTO_INCREMENT` предыдущим запросом.
mysql_kill() | Уничтожает заданный поток.
mysql_list_dbs() | Возвращает имена баз данных, совпадающие с простым регулярным выражением.
mysql_list_fields() | Возвращает имена полей, совпадающих с простым регулярным выражением.
mysql_list_processes() | Возвращает список текущих потоков на сервере.
mysql_list_tables() | Возвращает имена таблиц, совпадающих с простым регулярным выражением.
mysql_num_fields() | Возвращает количество столбцов в результирующем наборе.
mysql_num_rows() | Возвращает количество строк в результирующем наборе.
mysql_options() | Устанавливает параметры соединения для `mysql_connect()`.
mysql_ping() | Проверяет, работает ли данное соединение с сервером, и восстанавливает соединение при необходимости.
mysql_query() | Выполняет SQL-запрос, заданный в виде строки с нулевым символом в конце.
mysql_real_connect() | Создает соединение с сервером баз данных MySQL.
mysql_real_escape_string() | Экранирует специальные символы в строке, чтобы обеспечить возможность использования ее в команде SQL, с учетом установленной для данного соединения кодировки.
mysql_real_query() | Выполняет SQL-запрос, заданный в виде фиксированной строки.
mysql_reload() | Предписывает серверу перегрузить таблицы привилегий.
mysql_row_seek() Устанавливает курсор на заданную строку в результирующем наборе, используя величину, возвращенную из `mysql_row_tell()`.
mysql_row_tell() | Возвращает положение курсора строки.
mysql_select_db() | Выбирает базу данных.
mysql_shutdown() | Останавливает сервер баз данных.
mysql_stat() | Возвращает информацию о текущем статусе сервера баз данных в виде строки.
mysql_store_result() | Извлекает полный результирующий набор для данного клиента.
mysql_thread_id() | Возвращает идентификатор текущего потока.
mysql_thread_safe() | Возвращает 1, если клиенты скомпилированы как поддерживающие потоки.
mysql_use_result() | Инициализирует построчное извлечение результирующего набора.

При подсоединения к серверу необходимо вызвать функцию `mysql_init()` для инициализации дескриптора соединения, затем с этим дескриптором вызвать функцию `mysql_real_connect()` (которая содержит такую информацию, как имя данного хоста, имя пользователя и пароль). После соединения функция `mysql_real_connect()` устанавливает флаг `reconnect` (часть данной структуры MYSQL) в значение `1`. Этот флаг указывает, что в случае, если запрос не может быть выполнен из-за потери соединения, следует попытаться восстановить соединение с сервером до окончательного отказа от него. Для закрытия соединения вызывается функция `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()` состоит в том, что, поскольку все строки выбраны и находятся у клиента, то возможен не только последовательный доступ к строкам. В результирующем наборе данных можно перемещаться назад и вперед в, используя функции `mysql_data_seek()` или `mysql_row_seek()`, чтобы изменить положение текущей строки внутри результирующего набора. Можно также узнать количество находящихся в нем строк, вызвав функцию `mysql_num_rows()`. С другой стороны, для `mysql_store_result()` требования к памяти могут быть очень высокими для обширных результирующих наборов, что может привести к нехватке памяти.

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

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

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

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

### 8.4.3 Описание функций интерфейса C

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

Функции, возвращающие величину, обычно возвращают указатель или целое число. Если не указано иначе, то функции, возвращающие указатель, возвращают величину не-`NULL` при успешном выполнении или величину `NULL`, указывающую на ошибку, а функции, возвращающие целое число, возвращают нуль при успешном выполнении или ненулевую величину при возникновении ошибки. Следует учитывать, что термин ``ненулевая величина'' означает именно это. Если в описании функции не сказано иначе, то не следует пробовать интерпретировать эту величину иначе, чем нуль:

    if (result)		 /* правильно */
       ... error ...
    if (result < 0)		 /* неправильно */
       ... error ...
    if (result == -1)	 /* неправильно */
       ... error ...

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

#### 8.4.3.1 `mysql_affected_rows()`

`my_ulonglong mysql_affected_rows(MYSQL *mysql)`

#### Описание

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

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

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

#### Ошибки

Нет.

#### Пример

    mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10");
    printf("%ld products updated",(long) mysql_affected_rows(&mysql));

Если указывается флаг `CLIENT_FOUND_ROWS` при подключении к `mysqld`, то `mysql_affected_rows()` возвратит количество строк, соответствующих выражению `WHERE` для команд `UPDATE`.

Следует отметить, что при использовании команды `REPLACE` функция `mysql_affected_rows()` возвратит значение 2, если новая строка заменила старую. Это происходит по той причине, что в данном случае одна строка была внесена после того как дублирующая была удалена.

#### 8.4.3.2 `mysql_change_user()`

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

#### Описание

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

Эта функция была введена в версию MySQL 3.23.3.

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

Параметр `db` может быть установлен в `NULL`, если база данных по умолчанию не нужна.

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

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

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

#### Ошибки

Те же, что и для `mysql_real_connect()`.

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.
`ER_UNKNOWN_COM_ERROR`
  Сервер MySQL не обеспечивает выполнение этой команды (возможно, старая версия сервера)
`ER_ACCESS_DENIED_ERROR`
  Пользователь или пароль ошибочны.
`ER_BAD_DB_ERROR`
  Данная база данных не существует.
`ER_DBACCESS_DENIED_ERROR`
  Данный пользователь не имеет прав доступа к этой базе данных.
`ER_WRONG_DB_NAME`
  Имя базы данных было слишком длинным.

#### Пример

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

#### 8.4.3.3 `mysql_character_set_name()`

`const char *mysql_character_set_name(MYSQL *mysql)`

#### Описание

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

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

Кодировка, установленная по умолчанию.

#### Ошибки

Нет.

#### 8.4.3.4 `mysql_close()`

`void mysql_close(MYSQL *mysql)`

#### Описание

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

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

Нет.

#### Ошибки

Нет.

#### 8.4.3.5 `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()` нельзя выполнять никакие другие функции интерфейса, за исключением `mysql_get_client_info()`.

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

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

Те же, что и для `mysql_real_connect()`.

#### Ошибки

Те же, что и для `mysql_real_connect()`.

#### 8.4.3.6 `mysql_create_db()`

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

#### Описание

Создает базу данных, указанную в параметре `db`.

Данная функция не рекомендуется. Вместо нее предпочтительно использовать функцию `mysql_query()` для выполнения SQL-команды `CREATE DATABASE`.

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

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

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### Пример

    if(mysql_create_db(&mysql, "my_database"))
    {
      fprintf(stderr, "Failed to create new database. Error: %s\n", mysql_error(&mysql));
    }

#### 8.4.3.7 `mysql_data_seek()`

`void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset)`

#### Описание

Ищет произвольную строку в результирующем наборе запроса. Для этого требуется, чтобы структура результирующего набора содержала целиком весь результат данного запроса, поэтому `mysql_data_seek()` может использоваться только в сочетании с `mysql_store_result()`, но не с `mysql_use_result()`.

Адрес смещения должен быть величиной в диапазоне от 0 до `mysql_num_rows(result)-1`.

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

Нет.

#### Ошибки

Нет.

#### 8.4.3.8 `mysql_debug()`

`void mysql_debug(const char *debug)`

#### Описание

Выполняет отладочные операции `DBUG_PUSH` с заданной строкой. Функция `mysql_debug()` использует отладочную библиотеку `Fred Fish debug`. Для использования этой функции необходимо компилировать библиотеку клиента с поддержкой отладки (см. разделы section E.1 Отладка сервера MySQL и see section E.2 Отладка клиента MySQL).

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

Нет.

#### Ошибки

Нет.

#### Пример

Представленный здесь вызов функции заставляет библиотеку клиента генерировать трассировочный файл в каталоге ``/tmp/client.trace'` на клиентской машине:

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

#### 8.4.3.9 `mysql_drop_db()`

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

#### Описание

Уничтожает базу данных, указанную в параметре `db`.

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

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

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

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### Пример

    if(mysql_drop_db(&mysql, "my_database"))
    fprintf(stderr, "Failed to drop the database: Error: %s\n", mysql_error(&mysql));

#### 8.4.3.10 `mysql_dump_debug_info()`

`int mysql_dump_debug_info(MYSQL *mysql)`

#### Описание

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

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

Нуль, если команда выполнена успешно. Ненулевая величина, если произошла ошибка.

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### 8.4.3.11 `mysql_eof()`

`my_bool mysql_eof(MYSQL_RES *result)`

#### Описание

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

Функция `mysql_eof()` определяет, была ли данная строка последней из прочитанных в результирующем наборе данных.

Если результирующий набор получен путем успешного вызова функции `mysql_store_result()`, то данный клиент получает полный набор данных за одну операцию. В этом случае возврат `NULL` из `mysql_fetch_row()` всегда означает, что достигнут конец результирующего набора и нет необходимости в вызове функции `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)))
    {
    	// делаем что-то с данными
    }
    if(!mysql_eof(result)) // mysql_fetch_row() сбойнул из-за ошибки
    {
    	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)))
    {
    	// что-то делаем с данными
    }
    if(mysql_errno(&mysql)) // mysql_fetch_row() сбойнул из-за ошибки
    {
    fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
    }

#### 8.4.3.12 `mysql_errno()`

`unsigned int mysql_errno(MYSQL *mysql)`

#### Описание

Для соединения, указанного в `mysql`, функция `mysql_errno()` возвращает код ошибки для последней запущенной функции интерфейса, которая может быть успешной или не выполниться. Возвращение нулевой величины означает, что ошибка не возникала. Номера сообщений об ошибке для клиентов перечислены в заголовочном файле MySQL ``errmsg.h'`. Номера серверных сообщений об ошибке даны в файле ``mysqld_error.h'`. В исходном дистрибутиве MySQL можно найти полный список сообщений об ошибках и номеров ошибок в файле ``Docs/mysqld_error.txt'`.

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

Значение кода ошибки. Нуль, если ошибка не возникала.

#### Ошибки

Нет.

#### 8.4.3.13 `mysql_error()`

`char *mysql_error(MYSQL *mysql)`

#### Описание

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

    if(mysql_errno(&mysql))
    {
    	// ошибка  возникла
    }
    if(mysql_error(&mysql)[0] != '\0')
    {
    	// ошибка возникла
    }

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

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

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

#### Ошибки

Нет.

#### 8.4.3.14 `mysql_escape_string()`

Вместо этой функции следует использовать функцию `mysql_real_escape_string()`!

Данная функция идентична функции `mysql_real_escape_string()`, за исключением того, что `mysql_real_escape_string()` принимает дескриптор соединения в качестве своего первого аргумента и экранирует строку в соответствии с текущей кодировкой. Функция `mysql_escape_string()` не требует параметров соединения в качестве аргумента и не учитывает установки текущей кодировки.

#### 8.4.3.15 `mysql_fetch_field()`

`MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)`

#### Описание

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

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

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

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

Структура `MYSQL_FIELD` для текущего столбца. `NULL`, если полей больше не остается.

#### Ошибки

Нет.

#### Пример

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

#### 8.4.3.16 `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);
    }

#### 8.4.3.17 `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);
    }

#### 8.4.3.18 `mysql_fetch_lengths()`

`unsigned long *mysql_fetch_lengths(MYSQL_RES *result)`

#### Описание

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

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

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

Массив беззнаковых целых чисел, представляющий собой размер каждого столбца (не включая конечные нулевые символы). `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]);
    	}
    }

#### 8.4.3.19 `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`, если нет больше строк для извлечения или произошла ошибка.

#### Ошибки

`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### Пример

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

#### 8.4.3.20 `mysql_field_count()`

`unsigned int mysql_field_count(MYSQL *mysql)`

При использовании более ранней, чем 3.22.24, версии MySQL необходимо вместо этого выражения использовать следующее: `unsigned int mysql_num_fields(MYSQL *mysql)`.

#### Описание

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

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

See section 8.4.6.1 Почему после успешных возвратов функции `mysql_query()` функция `mysql_store_result()` иногда возвращает `NULL`?.

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

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

#### Ошибки

Нет.

#### Пример

    MYSQL_RES *result;
    unsigned int num_fields;
    unsigned int num_rows;

    if (mysql_query(&mysql,query_string))
    {
    	// ошибка
    }
    else // запрос выполнен, обработка возвращенных им данных
    {
    	result = mysql_store_result(&mysql);
    	if (result) // содержит строки
    	{
    		num_fields = mysql_num_fields(result);
    		// извлечение строк, затем вызов mysql_free_result(result)
    	}
    	else // mysql_store_result() не вернула ничего; может ли что-либо вернуть?
    	{
    		if(mysql_field_count(&mysql) == 0)
    		{
    			// запрос не возвращает данные
    			// (запрос не был вида SELECT)
    			num_rows = mysql_affected_rows(&mysql);
    		}
    		else // mysql_store_result() должна была вернуть данные
    		{
    			fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
    		}
    	}
    }

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

#### 8.4.3.21 `mysql_field_seek()`

`MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)`

#### Описание

Устанавливает курсор поля в заданную позицию. Дальнейший вызов функции `mysql_fetch_field()` будет извлекать определение данного поля в столбце, ассоциированном с данной позицией курсора.

Для поиска начала строки необходимо установить величину `offset` в нуль.

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

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

#### Ошибки

Нет.

#### 8.4.3.22 `mysql_field_tell()`

`MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)`

#### Описание

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

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

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

#### Ошибки

Нет.

#### 8.4.3.23 `mysql_free_result()`

`void mysql_free_result(MYSQL_RES *result)`

#### Описание

Освобождает память, выделенную для результирующего набора данных функциями `mysql_store_result()`, `mysql_use_result()`, `mysql_list_dbs()` и т.д. После выполнения операций с результирующим набором необходимо освободить используемую под него память вызовом функции `mysql_free_result()`.

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

Нет.

#### Ошибки

Нет.

#### 8.4.3.24 `mysql_get_client_info()`

`char *mysql_get_client_info(void)`

#### Описание

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

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

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

#### Ошибки

Нет.

#### 8.4.3.25 `mysql_get_server_version()`

`unsigned long mysql_get_server_version(MYSQL *mysql)`

#### Описание

Возвращает номер версии сервера как целое число (новое с 4.1)

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

Число, представляющее версию сервера MySQL, в следующем формате:

main_version*10000 + minor_version *100 + sub_version

Например, 4.1.0 будет возвращена как 40100.

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

#### Ошибки

Нет.

#### 8.4.3.26 `mysql_get_host_info()`

`char *mysql_get_host_info(MYSQL *mysql)`

#### Описание

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

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

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

#### Ошибки

Нет.

#### 8.4.3.27 `mysql_get_proto_info()`

`unsigned int mysql_get_proto_info(MYSQL *mysql)`

#### Описание

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

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

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

#### Ошибки

Нет.

#### 8.4.3.28 `mysql_get_server_info()`

`char *mysql_get_server_info(MYSQL *mysql)`

#### Описание

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

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

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

#### Ошибки

Нет.

#### 8.4.3.29 `mysql_info()`

`char *mysql_info(MYSQL *mysql)`

#### Описание

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

`INSERT INTO ... SELECT ...`
  Формат строки: `Records: 100 Duplicates: 0 Warnings: 0`
`INSERT INTO ... VALUES (...),(...),(...)...`
  Формат строки: `Records: 3 Duplicates: 0 Warnings: 0`
`LOAD DATA INFILE ...`
  Формат строки: `Records: 1 Deleted: 0 Skipped: 0 Warnings: 0`
`ALTER TABLE`
  Формат строки: `Records: 3 Duplicates: 0 Warnings: 0`
`UPDATE`
  Формат строки: `Rows matched: 40 Changed: 40 Warnings: 0`

Следует учитывать, что функция `mysql_info()` возвращает величину не-`NULL` для команды `INSERT ... VALUES`, только если в данной команде заданы множественные списки величин.

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

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

#### Ошибки

Нет.

#### 8.4.3.30 `mysql_init()`

`MYSQL *mysql_init(MYSQL *mysql)`

#### Описание

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

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

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

#### Ошибки

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

#### 8.4.3.31 `mysql_insert_id()`

`my_ulonglong mysql_insert_id(MYSQL *mysql)`

#### Описание

Возвращает идентификатор `ID`, сгенерированный для столбца `AUTO_INCREMENT` предыдущим запросом. Эту функцию следует использовать после выполнения запроса `INSERT` в таблице, содержащей поле `AUTO_INCREMENT`.

Следует учитывать, что функция `mysql_insert_id()` возвращает 0, если предыдущий запрос не сформировал величину `AUTO_INCREMENT`. Если необходимо сохранить эту величину в дальнейшем, то следует позаботиться о вызове функции `mysql_insert_id()` немедленно после запроса, который создает указанную величину.

Функция `mysql_insert_id()` обновляется после команд `INSERT` и `UPDATE`, которые генерируют величину `AUTO_INCREMENT` или устанавливают величину столбца в значение `LAST_INSERT_ID(expr)`. See section 6.3.6.2 Разные функции.

Следует также иметь в виду, что величина SQL-функции `LAST_INSERT_ID()` всегда содержит самое последнее сгенерированное значение `AUTO_INCREMENT` и не обновляется между запросами, так как величина этой функции сохраняется сервером.

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

Величина поля `AUTO_INCREMENT`, обновленного предыдущим запросом. Возвращает нуль, если перед этим не было запроса в данном соединении или если данный запрос не обновил величину `AUTO_INCREMENT`.

#### Ошибки

Нет.

#### 8.4.3.32 `mysql_kill()`

`int mysql_kill(MYSQL *mysql, unsigned long pid)`

#### Описание

Предписывает серверу уничтожить поток, указанный в аргументе `pid`.

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

Нуль при успешном выполнении. Отличная от нуля величина при ошибке.

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### 8.4.3.33 `mysql_list_dbs()`

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

#### Описание

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

Результирующий набор необходимо освободить с помощью функции `mysql_free_result()`.

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

Результирующий набор `MYSQL_RES` при успешном выполнении. `NULL`, если произошла ошибка.

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_OUT_OF_MEMORY`
  Нехватка памяти.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### 8.4.3.34 `mysql_list_fields()`

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

#### Описание

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

Следует учитывать, что рекомендуется использовать команду `SHOW COLUMNS FROM tbl_nam`e вместо функции `mysql_list_fields()`.

Результирующий набор необходимо освободить с помощью функции `mysql_free_result()`.

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

Результирующий набор `MYSQL_RES` при успешном выполнении. `NULL`, если произошла ошибка.

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### 8.4.3.35 `mysql_list_processes()`

`MYSQL_RES *mysql_list_processes(MYSQL *mysql)`

#### Описание

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

Результирующий набор необходимо освободить с помощью функции `mysql_free_result()`.

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

Результирующий набор `MYSQL_RES` при успешном выполнении. `NULL`, если произошла ошибка.

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### 8.4.3.36 `mysql_list_tables()`

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

#### Описание

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

Результирующий набор необходимо освободить с помощью функции `mysql_free_result()`.

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

Результирующий набор `MYSQL_RES` при успешном выполнении. `NULL`, если произошла ошибка.

#### Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в ненадлежащем порядке. CR_SERVER_GONE_ERROR Сервер MySQL неожиданно завершил работу. CR_SERVER_LOST Соединение с сервером прервалось в процессе данного запроса. CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

#### 8.4.3.37 `mysql_num_fields()`

`unsigned int mysql_num_fields(MYSQL_RES *result)`

или

`unsigned int mysql_num_fields(MYSQL *mysql)`

Вторая форма не работает на версии MySQL 3.22.24 или более новой. Вместо аргумента в параметре `MYSQL*` необходимо использовать выражение `unsigned int mysql_field_count(MYSQL *mysql)`

#### Описание

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

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

See section 8.4.6.1 Почему после успешных возвратов функции `mysql_query()` функция `mysql_store_result()` иногда возвращает `NULL`?.

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

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

#### Ошибки

Нет.

#### Пример

    MYSQL_RES *result;
    unsigned int num_fields;
    unsigned int num_rows;

    if (mysql_query(&mysql,query_string))
    {
    	// ошибка
    }
    else // запрос выполнен, обработка возвращенных им данных
    {
    	result = mysql_store_result(&mysql);
    	if (result) // содержит строки {
    		num_fields = mysql_num_fields(result);
    		// извлечение строк, затем вызов mysql_free_result(result)
    	}
    	else // mysql_store_result()не вернула ничего; может ли что-либо вернуть?
    	{
    		if (mysql_errno(&mysql))
    		{
    			fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
    		}
    		else if (mysql_field_count(&mysql) == 0)
    		{
    			// запрос не возвращает данные
    			// (запрос не был вида SELECT)
    			num_rows = mysql_affected_rows(&mysql);
    		}
    	}
    }

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

#### 8.4.3.38 `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()` не будет возвращать правильную величину до тех пор, пока все строки в результирующем наборе не будут извлечены.

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

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

#### Ошибки

Нет.

#### 8.4.3.39 `mysql_options()`

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

#### Описание

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

Функция `mysql_options()` должна вызываться после функции `mysql_init()` и перед функцией `mysql_connect()` или `mysql_real_connect()`.

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

Возможные значения опций:

Опция | Тип аргумента | Функция
`MYSQL_OPT_CONNECT_TIMEOUT` | `unsigned int *` | Время ожидания для соединения в секундах.
`MYSQL_OPT_COMPRESS` | Не используется | Использовать сжатие в клиент-серверном протоколе.
`MYSQL_OPT_LOCAL_INFILE` | Опциональный указатель на uint | Если указатель не задан или указывает на `unsigned int != 0` команда `LOAD LOCAL INFILE` разрешена.
`MYSQL_OPT_NAMED_PIPE` | Не используется | Использовать именованные каналы для соединения с сервером MySQL на NT.
`MYSQL_INIT_COMMAND` | `char *` | Команда для исполнения при подключении к серверу MySQL. При восстановлении соединения будет снова автоматически выполнена.
`MYSQL_READ_DEFAULT_FILE` | `char *` | Читать опции из указанного файла опций вместо чтения из файла ``my.cnf'`.
`MYSQL_READ_DEFAULT_GROUP` | `char *` | Читать опции из указанной группы из файла ``my.cnf'` или из файла заданного в `MYSQL_READ_DEFAULT_FILE`.

Следует помнить, что группа `client` читается всегда при использовании `MYSQL_READ_DEFAULT_FILE` или `MYSQL_READ_DEFAULT_GROUP`.

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

Опция | Описание
`connect-timeout` | Время ожидания для соединения в секундах. Для Linux это время ожидания используется также для ожидания первого ответа с сервера.
`compress` | Использовать сжатие в клиент-серверном протоколе.
`database` | Подключиться к этой базе данных, если никакая база данных не была указана в данной команде подключения.
`debug` | Опции отладки.
`disable-local-infile` | Блокировка использования `LOAD DATA LOCAL`.
`host` | Имя хоста по умолчанию.
`init-command` | Команда для исполнения при подключении к серверу MySQL. При восстановлении соединения будет снова автоматически выполнена.
`interactive-timeout` | Аналогично заданию `CLIENT_INTERACTIVE` в `mysql_real_connect()`. See section 8.4.3.42 `mysql_real_connect()`.
`local-infile[=(0|1)]` | Если аргумент не задан или указан аргумент `!= 0`, то разрешено использование `LOAD DATA LOCAL`.
`max_allowed_packet` | Максимальный размер пакета, который клиент может читать с сервера.
`password` | Пароль по умолчанию.
`pipe` | Использовать именованные каналы для соединения с сервером MySQL на NT.
`protocol=(TCP | SOCKET | PIPE | MEMORY)` | Какой протокол использовать для подключения к серверу (новшество 4.1.0).
`port` | Номер порта по умолчанию.
`return-found-rows` | Предписывает `mysql_info()` возвращать найденные строки вместо обновления их при выполнении `UPDATE`.
`shared-memory-base-name=name` | Имя блока общей памяти (shared memory name), которое следует использовать для подключения к серверу (по умолчанию "MySQL"). Новшество в MySQL 4.1.
`socket` | Номер сокета по умолчанию.
`user` | Пользователь по умолчанию.

Следует помнить, что `timeout` замещен на `connect-timeout`, но `timeout` временно еще работает.

Для более подробной информации о файлах опций см. раздел See section 4.1.2 Файлы параметров ``my.cnf'`.

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

Нуль при успешном выполнении. Величина, отличная от нуля, если используется неизвестная опция.

#### Пример

    MYSQL mysql;

    mysql_init(&mysql);
    mysql_options(&mysql,MYSQL_OPT_COMPRESS,0);
    mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc");
    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));
    }

Вышеприведенный пример запрашивает клиента использовать сжатый клиент-серверный протокол и читать дополнительные опции из секции `odbc` в файле ``my.cnf'`.

#### 8.4.3.40 `mysql_ping()`

`int mysql_ping(MYSQL *mysql)`

#### Описание

Проверяет, работает ли данное соединение с сервером. Если соединение прервано, то пытается автоматически восстановить его.

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

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

Нуль, если сервер в активном состоянии. Величина, отличная от нуля, если произошла ошибка.

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### 8.4.3.41 `mysql_query()`

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

#### Описание

Выполняет запрос SQL, указанный в аргументе `query` в виде строки с нулевыми окончаниями. Данный запрос должен состоять из одной команды SQL. Нельзя добавлять к этой команде в качестве завершающих элементов точку с запятой (``;'`) или `\g`.

Функция `mysql_query()` не может использоваться для запросов, содержащих двоичные данные; вместо этого необходимо использовать функцию `mysql_real_query()` (двоичные данные могут содержать символ ``\0'`, который `mysql_query()` интерпретирует как окончание строки запроса).

Для проверки, вернул данный запрос результирующий набор или нет, можно использовать функцию `mysql_field_count()`. See section 8.4.3.20 `mysql_field_count()`.

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

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

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### 8.4.3.42 `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 int client_flag)`

Описание

Функция `mysql_real_connect()` пытается установить соединение с сервером баз данных MySQL, работающим на хосте `host`. До успешного завершения функции `mysql_real_connect()` нельзя выполнять никакие другие функции интерфейса, за исключением `mysql_get_client_info()`.

Параметры этой функции указываются следующим образом:

- Первым параметром должен быть указатель существующей структуры `MYSQL`. До вызова функции `mysql_real_connect`() необходимо вызвать функцию `mysql_init()` для инициализации данной структуры `MYSQL`. Вызов функции `mysql_options()` позволяет изменить многие опции данного соединения. See section 8.4.3.39 `mysql_options()`.
- `host` может быть как именем хоста, так и IP-адресом. Если host равен `NULL` или строке `"localhost"`, то подразумевается соединение с локальным хостом. Если операционная система поддерживает сокеты (Unix) или именованные каналы (Windows), то они используются вместо протокола TCP/IP для соединения с сервером.
- Параметр user содержит имя данного пользователя MySQL. Если параметр user равен `NULL`, то подразумевается текущий пользователь. Под операционной системой Unix, это будет текущее имя входа в систему. Под Windows ODBC имя пользователя должно быть указано явным образом. См. раздел See section 8.3.2 Как заполнять различные поля в Администраторе ODBC.
- Параметр `passwd` содержит пароль для user. Если параметр `passwd` равен `NULL`, то только записи в таблице `user` для пользователя, имеющего чистое (пустое) поле пароля, будут проверяться на совпадение. Это дает возможность администратору базы данных устанавливать систему прав MySQL таким образом, что пользователи получают различные права, в зависимости от того, имеют они или нет установленный пароль. Замечание: не следует пытаться шифровать пароль перед вызовом функции `mysql_real_connect()`; шифрование пароля производится автоматически библиотекой.
- Параметр `db` представляет собой имя базы данных. Если параметр `db` не равен `NULL`, то данное соединение установит эту величину в качестве базы данных по умолчанию.
- Если параметр `port` не равен 0, то данная величина будет использована в качестве порта для соединения TCP/IP. Следует учитывать, что тип соединения определяется параметром `host`.
- Если параметр `unix_socket` не равен `NULL`, то данная строка указывает сокет или именованный канал, который следует использовать. Следует учитывать, что тип соединения определяется параметром `host`.
- Величина параметра `client_flag` обычно равна 0, но при особых обстоятельствах может быть установлена как комбинация следующих флагов:

  Имя флага | Описание флага
  `CLIENT_COMPRESS` | Использовать сжатие в протоколе.
  `CLIENT_FOUND_ROWS` | Возвращать количество найденных (совпавших) строк, а не количество строк, подвергшихся воздействию.
  `CLIENT_IGNORE_SPACE` | Допускать пробелы после имен функций. Сделать имена всех функций зарезервированными словами.
  `CLIENT_INTERACTIVE` | Допускать простой длительностью `interactive_timeout` секунд (вместо `wait_timeout` секунд) перед закрытием данного соединения.
  `CLIENT_NO_SCHEMA` | Запретить использование формы `db_name.tbl_name.col_name`. Это делается для ODBC и заставляет синтаксический анализатор генерировать ошибку при использовании данного синтаксиса, который полезен для выявления ошибок в некоторых программах ODBC.
  `CLIENT_ODBC` | Клиентом является клиент ODBC. Настраивает `mysqld` для большей совместимости с ODBC.
  `CLIENT_SSL` | Использовать SSL (протокол шифрования).

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

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

#### Ошибки

`CR_CONN_HOST_ERROR`
  Не удалось соединиться с сервером MySQL.
`CR_CONNECTION_ERROR`
  Не удалось соединиться с локальным сервером MySQL.
`CR_IPSOCK_ERROR`
  Не удалось создать IP-сокет.
`CR_OUT_OF_MEMORY`
  Недостаток памяти.
`CR_SOCKET_CREATE_ERROR`
  Не удалось создать Unix сокет.
`CR_UNKNOWN_HOST`
  Не удалось найти IP-адрес для данного имени хоста.
`CR_VERSION_ERROR`
  Несоответствие протокола, что явилось результатом попытки соединения с сервером с клиентской библиотекой, использующей иную версию протокола. Это может произойти при использовании очень старой клиентской библиотеки для подключения к новому серверу, при запуске которого не была установлена опция `--old-protocol`.
`CR_NAMEDPIPEOPEN_ERROR`
  Не удалось создать именованный канал на Windows.
`CR_NAMEDPIPEWAIT_ERROR`
  Не удалось дождаться именованного канала на Windows.
`CR_NAMEDPIPESETSTATE_ERROR`
  Не удалось получить обработчик канала на Windows.
`CR_SERVER_LOST`
  Если connect_timeout > 0 и требовалось больше, чем connect_timeout секунд для соединения с сервером или если сервер прекратил работу во время выполнения init-command.

#### Пример

    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`. Этот флаг показывает, что в случае, если запрос не может быть выполнен из-за потери соединения, то следует попытаться восстановить соединение прежде, чем отказаться от него.

#### 8.4.3.43 `mysql_real_escape_string()`

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

#### Описание

Эта функция используется для создания допустимой SQL- строки, которую можно использовать в команде SQL. See section 6.1.1.1 Cтроки.

Строка из секции `from` кодируется в экранированную SQL-строку, принимая во внимание текущую кодировку данного соединения. Результат помещается в секцию to с добавлением концевого нулевого байта. Кодируются следующие символы: `NUL` (ASCII 0), ``\n'`, ``\r'`, ``\'`, ``''`, ``"'` и Ctrl-Z (see section 6.1.1 Литералы: представление строк и чисел). (Строго говоря, MySQL требует только чтобы обратная косая черта и кавычки, используемые для квотинга строк в запросе, были проэкранированы. Эта функция экранирует и другие символы, делая их более легкими для чтения в журнальных файлах.)

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

#### Пример

    char query[1000],*end;

    end = strmov(query,"INSERT INTO test_table values(");
    *end++ = '\'';
    end += mysql_real_escape_string(&mysql, end,"What's this",11);
    *end++ = '\'';
    *end++ = ',';
    *end++ = '\'';
    end += mysql_real_escape_string(&mysql, end,"binary data: \0\r\n",16);
    *end++ = '\'';
    *end++ = ')';

    if (mysql_real_query(&mysql,query,(unsigned int) (end - query)))
    {
    	fprintf(stderr, "Failed to insert row, Error: %s\n",
    	mysql_error(&mysql));
    }

Функция `strmov()`, использованная в этом примере, присутствует в библиотеке `mysqlclient` и работает подобно функции `strcpy()`, но возвращает указатель на концевой нуль первого параметра.

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

Длина величины, помещенной в секции to, не включая концевой нулевой символ.

#### Ошибки

Нет.

#### 8.4.3.44 `mysql_real_query()`

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

#### Описание

Выполняет SQL-запрос, указанный в query, который должен быть строкой длиною `length` байтов. Данный запрос должен состоять из одной команды SQL. Нельзя добавлять к этой команде в качестве завершающих элементов точку с запятой (``;'`) или `\g`.

Необходимо использовать функцию `mysql_real_query()` вместо функции `mysql_query()`для запросов, содержащих двоичные данные, поскольку двоичные данные могут содержать символ ``\0'`. Кроме того, функция `mysql_real_query()` быстрее, чем `mysql_query()` так как она не вызывает функцию `strlen()` в строке запроса.

Для проверки того, вернул данный запрос результирующий набор или нет, можно использовать функцию `mysql_field_count()`. See section 8.4.3.20 `mysql_field_count()`.

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

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

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### 8.4.3.45 `mysql_reload()`

`int mysql_reload(MYSQL *mysql)`

#### Описание

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

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

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

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

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### 8.4.3.46 `mysql_row_seek()`

`MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)`

#### Описание

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

Адрес смещения должен быть величиной, возвращенной в результате вызова функций `mysql_row_tell()` или `mysql_row_seek()`. Эта величина не является номером строки, поэтому для проведения поиска строки внутри результирующего набора по номеру строки вместо данной функции следует использовать функцию `mysql_data_seek()`.

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

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

#### Ошибки

Нет.

#### 8.4.3.47 `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()`.

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

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

#### Ошибки

Нет.

#### 8.4.3.48 `mysql_select_db()`

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

#### Описание

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

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

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

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

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### 8.4.3.49 `mysql_shutdown()`

`int mysql_shutdown(MYSQL *mysql)`

#### Описание

Останавливает сервер баз данных. Подключенный пользователь должен иметь права `SHUTDOWN`.

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

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

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### 8.4.3.50 `mysql_stat()`

`char *mysql_stat(MYSQL *mysql)`

#### Описание

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

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

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

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### 8.4.3.51 `mysql_store_result()`

`MYSQL_RES *mysql_store_result(MYSQL *mysql)`

#### Описание

Функцию `mysql_store_result()` или `mysql_use_result()` необходимо вызывать после каждого выполненного запроса, извлекающего данные (`SELECT`, `SHOW`, `DESCRIBE`, `EXPLAIN`).

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

Для проверки того, вернул данный запрос результирующий набор или нет, можно использовать функцию `mysql_field_count()`. See section 8.4.3.20 `mysql_field_count()`.

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

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

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

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

Если была вызвана функция `mysql_store_result()` и полученный результат не является нулевым указателем, то можно вызвать функцию `mysql_num_rows()` для определения количества строк в результирующем наборе.

Можно вызвать функцию `mysql_fetch_row()` для выборки строк из результирующего набора или функции `mysql_row_seek()` и `mysql_row_tell()` для получения или установки положения текущей строки внутри данного результирующего набора.

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

See section 8.4.6.1 Почему после успешных возвратов функции `mysql_query()` функция `mysql_store_result()` иногда возвращает `NULL`?.

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

Результирующая структура `MYSQL_RES` с результатами. `NULL`, если произошла ошибка.

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_OUT_OF_MEMORY`
  Нехватка памяти.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

#### 8.4.3.52 `mysql_thread_id()`

`unsigned long mysql_thread_id(MYSQL *mysql)`

#### Описание

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

Если соединение прерывается и осуществляется его восстановление с помощью функции `mysql_ping()`, то идентификатор данного потока изменится. Это означает, что нельзя получить идентификатор данного потока и хранить его для последующего использования. Следует определять его, когда в этом есть необходимость.

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

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

#### Ошибки

Нет.

#### 8.4.3.53 `mysql_use_result()`

`MYSQL_RES *mysql_use_result(MYSQL *mysql)`

#### Описание

Функцию `mysql_store_result()` или `mysql_use_result()` необходимо вызывать после каждого выполненного запроса, извлекающего данные (`SELECT`, `SHOW`, `DESCRIBE`, `EXPLAIN`).

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

С другой стороны, функцию `mysql_use_result()` нельзя использовать, если выполняется много операций по обработке каждой строки на клиентской стороне, или если вывод делается на терминал, на котором пользователь может нажать `^S` (остановить вывод).

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

При использовании `mysql_use_result()` необходимо выполнять `mysql_fetch_row()`, пока не возвратится величина `NULL`, в противном случае невыбранные строки данного запроса будут возвращены как часть результирующего набора для следующего запроса. Если вы забыли сделать это, то интерфейс C будет выдавать ошибку `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()` сразу же после окончания действий с результирующим набором.

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

Результирующая структура `MYSQL_RES` с результатами. `NULL`, если произошла ошибка.

#### Ошибки

`CR_COMMANDS_OUT_OF_SYNC`
  Команды были выполнены в ненадлежащем порядке.
`CR_OUT_OF_MEMORY`
  Нехватка памяти.
`CR_SERVER_GONE_ERROR`
  Сервер MySQL неожиданно завершил работу.
`CR_SERVER_LOST`
  Соединение с сервером прервалось в процессе данного запроса.
`CR_UNKNOWN_ERROR`
  Произошла неизвестная ошибка.

### 8.4.4 Описания функций C, связанных с потоками

Эти функции необходимо вызывать для сборки клиента с поддержкой потоков. See section 8.4.8 Как создать клиентскую программу с потоками.

#### 8.4.4.1 `my_init()`

`void my_init(void)`

#### Описание

Данную функцию необходимо вызывать однажды во время запуска программы перед вызовом любой функции MySQL. Ее вызовом инициализируются необходимые для MySQL глобальные переменные. При использовании клиентской библиотеки, поддерживающей потоки, эта функция будет также вызывать функцию `mysql_thread_init()` для этого потока.

Данная функция вызывается автоматически функциями `mysql_init()`, `mysql_server_init()` и `mysql_connect()`.

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

Нет.

#### 8.4.4.2 `mysql_thread_init()`

`my_bool mysql_thread_init(void)`

#### Описание

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

Данная функция вызывается автоматически функциями `my_init()` и `mysql_connect()`.

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

Нет.

#### 8.4.4.3 `mysql_thread_end()`

`void mysql_thread_end(void)`

#### Описание

Данную функцию необходимо вызывать перед вызовом функции `pthread_exit()` для освобождения памяти, выделенной функцией `mysql_thread_init()`.

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

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

Нет.

#### 8.4.4.4 `mysql_thread_safe()`

`unsigned int mysql_thread_safe(void)`

#### Описание

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

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

1 - если данный клиент поддерживает потоки, 0 - в противном случае.

### 8.4.5 Описания функций C, доступных во встраиваемом сервере

Эти функции можно использовать при линковании с библиотекой встраиваемого сервера MySQL.

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

Если данная программа слинкована с `-lmysqlclient`, а не с `-lmysqld`, то эти функции не делают ничего. Это обеспечивает возможность выбора между встраиваемым сервером MySQL и автономным без какой-либо модификации кода.

#### 8.4.5.1 `mysql_server_init()`

`int mysql_server_init(int argc, char **argv, char **groups)`

#### Описание

Данную функцию необходимо вызывать только один раз во время работы программы, использующей встроенный сервер. Это функцию следует вызвать перед вызовом любой другой функции MySQL. Она запускает сервер и инициализирует все подсистемы (`mysys`, InnoDB и т.д.), используемые сервером. Без вызова этой функции произойдет аварийное завершение данной программы. При использовании пакета `DBUG`, поставляемого вместе с MySQL, данную функцию следует вызывать после функции `MY_INIT()`.

Аргументы `argc` и `argv` аналогичны аргументам в `main`(). Первый элемент аргумента `argv` игнорируется (обычно он содержит имя программы). Для удобства аргумент argc может быть равен 0 (нуль) - если не задано ни одного аргумента командной строки для данного сервера. `mysql_server_init()` делает копию аргументов, т.е. она безопастна для уничтожения `argv` или `groups` после вызова.

Аргумент `groups` представляет собой список строк, заканчивающийся `NULL`. Этот аргумент задает активные группы в файлах опций (see section 4.1.2 Файлы параметров ``my.cnf'`). Для удобства аргумент groups может быть равен `NULL` - в этом случае будут активны группы `[server]` и `[emedded]`.

#### Пример

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

    static char *server_args[] = {
      "this_program", /* эта строка не используется */
      "--datadir=.",
      "--key_buffer_size=32M"
    };

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

    int main(void) {
      mysql_server_init(sizeof(server_args) / sizeof(char *),
      server_args, server_groups);
      /* Здесь используются любые функции MySQL  API */
      mysql_server_end();
      return EXIT_SUCCESS;
    }

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

0 - если все в порядке, 1 - если произошла ошибка.

#### 8.4.5.2 `mysql_server_end()`

`void mysql_server_end(void)`

#### Описание

Эту функцию в программе необходимо вызывать только единожды, после всех остальных функций MySQL. Она останавливает `libmysqld`, встраиваемый сервер MySQL.

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

Нет.

### 8.4.6 Основные вопросы и проблемы в использовании интерфейса C

#### 8.4.6.1 Почему после успешных возвратов функции `mysql_query()` функция `mysql_store_result()` иногда возвращает `NULL`?

Для функции `mysql_store_result()` после успешного вызова функции `mysql_query()` возможен возврат величины `NULL`. Это может означать следующее:

- Произошел сбой в выполнении функции `mallow()` (например, если результирующий набор данных слишком велик).
- Данные не могли быть прочитаны (возникла ошибка в соединении). Запрос не вернул никаких данных (например, это был запрос вида `INSERT`, `UPDATE` или `DELETE`).

Проверить, вернула ли данная команда не пустой результирующий набор, всегда можно с помощью вызова функции `mysql_field_count()`. Если функция `mysql_field_count()` возвращает нуль, то данный результирующий набор является пустым и последний запрос представлял собой команду, которая не возвращает результирующие величины (например, `INSERT` или `DELETE`). Если функция `mysql_field_count()` возвращает величину, отличную от нуля, то данная команда должна была вернуть не пустой результат (см. описание функции `mysql_field_count()`).

Можно протестировать описанные ситуации на ошибку, вызывая функции `mysql_error()` или `mysql_errno()`.

#### 8.4.6.2 Какие результаты можно получить из запроса?

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

- Функция `mysql_affected_rows()` возвращает количество строк, подвергшихся воздействию во время последнего запроса при выполнении `INSERT`, `UPDATE` или `DELETE`. Исключение составляет случай использования команды `DELETE` без выражения `WHERE`, когда таблица воссоздается как пустая, а это намного быстрее! В таком случае функция `mysql_affected_rows()` в качестве количества подвергшихся воздействию записей возвращает нуль.
- Функция `mysql_num_rows()` возвращает количество строк в результирующем наборе данных. Функция `mysql_num_rows()` может вызываться сразу же после возвращения функции `mysql_store_result()`. Совместно с функцией `mysql_use_result()` функция `mysql_num_rows()` может вызываться только после того, как извлечены все строки с помощью функции `mysql_fetch_row()`.
- Функция `mysql_insert_id()` возвращает идентификатор, созданный последним запросом, внесшим строку в таблицу с автоинкрементным полем (`AUTO_INCREMENT`, `mysql_insert_id()`).
- Некоторые запросы (`LOAD DATA INFILE ...`, `INSERT INTO ... SELECT ...`, `UPDATE`) возвращают дополнительную информацию. Ее можно получить с помощью функции `mysql_info()`. Описание формата возвращаемой строки смотрите в описании функции `mysql_info()`. Если дополнительная информация отсутствует, то функция `mysql_info()` возвращает указатель `NULL`.

#### 8.4.6.3 Как получить уникальный идентификатор для последней внесенной строки?

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

Для извлечения этого `id` можно также использовать функцию `LAST_INSERT_ID()` в строке запроса, передаваемой в `mysql_query()`.

Для проверки, используется или нет поле `AUTO_INCREMENT`, можно выполнить следующий код. Этот код также проверяет, был ли данный запрос вида `INSERT` с использованием `AUTO_INCREMENT`:

    if (mysql_error(&mysql)[0] == 0 &&
    mysql_num_fields(result) == 0 &&
    mysql_insert_id(&mysql) != 0)
    {
    	used_id = mysql_insert_id(&mysql);
    }

Самое последнее сгенерированное значение идентификатора сохраняется на сервере в течение времени жизни данного соединения. Это значение не может быть изменено другим клиентом, более того, оно не будет изменено даже при обновлении другого столбца `AUTO_INCREMENT` конкретной величиной (т.е. не `NULL` или `0`).

Идентификатор, который был сгенерирован для одной таблицы, можно вставить в другую таблицу, используя команды SQL, как показано ниже:

    INSERT INTO foo (auto,text)
        VALUES(NULL,'text'); # генерация ID вставкой NULL
    INSERT INTO foo2 (id,text)
        VALUES(LAST_INSERT_ID(),'text'); # использование ID во второй таблице

#### 8.4.6.4 Проблемы линкования с интерфейсом C

При линковании программы с клиентской библиотекой C в некоторых системах могут возникать следующие проблемы:

    gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl

    Undefined        first referenced
     symbol          in file
    floor            /usr/local/lib/mysql/libmysqlclient.a(password.o)
    ld: fatal: Symbol referencing errors. No output written to client

Если это случилось в вашей системе, то необходимо подключить математическую библиотеку путем добавления параметра `-lm` в конец строки компилирования/линкования.

### 8.4.7 Сборка клиентских программ

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

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

Для того что бы сделать вышеизложенное более простым под Unix мы предоставляем для вас скрипт `mysql_config`. See section 4.8.9 `mysql_config`, Получение опций компиляции для компиляции клиентских программ.

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

    CFG=/usr/local/mysql/bin/mysql_config
    sh -c "gcc -o progname `$CFG --cflags` progname.c `$CFG --libs`"

`sh -c` необходимо чтобы оболочка не воспринимала вывод `mysql_config` как одно слово.

### 8.4.8 Как создать клиентскую программу с потоками

Клиентская библиотека почти безопасна при использовании в мультипоточном режиме. Наибольшая проблема заключается в том, что функции в ``net.c'`, читающие из сокетов, не поддерживают прерываний. Они были спроектированы исходя из предположения, что пользователь может захотеть иметь свой собственный аварийный сигнал, который способен прерывать слишком долгое чтение с сервера. При установке обработчиков прерываний для прерывания `SIGPIPE` управление сокетами должно быть поддерживающим потоки.

В более ранних бинарных поставках MySQL, которые мы (разработчики MySQL) распространяли с нашего веб-сайта (http://www.mysql.com/), клиентские библиотеки обычно не компилировались с возможностью поддержки потоков (бинарные поставки для Windows по умолчанию компилируются как поддерживающие потоки). Более новые бинарные поставки должны иметь как нормальную, так и поддерживающую потоки клиентскую библиотеку.

Чтобы получить поддерживающую потоки клиентскую программу с возможностью прерывать ее из других потоков и устанавливать блокировки по времени при соединении с сервером MySQL, необходимо использовать библиотеки `-lmysys`, `-lmystrings` и `-ldbug libraries`, а также код ``net_serv.o'`, используемый данным сервером.

Если нет необходимости в прерываниях или временных блокировках, то можно просто скомпилировать поддерживающую потоки клиентскую библиотеку (`mysqlclient_r`) и использовать ее (see section 8.4 Интерфейс C для MySQL). В этом случае нет необходимости заботиться об объектном файле net_serv.o или других библиотеках MySQL.

Если необходимо применять временные блокировки и прерывания при использовании поддерживающего потоки клиента, то можно с успехом использовать подпрограммы из файла ``thr_alarm.c'`. При использовании подпрограмм из библиотеки mysys следует помнить только о том, что сначала следует вызвать функцию `my_init()`! See section 8.4.4 Описания функций C, связанных с потоками.

Все функции, за исключением `mysql_real_connect()`, по умолчанию являются поддерживающими потоки. Ниже приводятся рекомендации, как следует компилировать поддерживающую потоки клиентскую библиотеку и использовать ее в этом режиме (замечания по функции `mysql_real_connect()` справедливы также и для функции `mysql_connect()`, но поскольку функция `mysql_connect()` не рекомендуется, то в любом случае следует использовать функцию `mysql_real_connect()`).

Для того чтобы сделать функцию `mysql_real_connect()` поддерживающей потоки, необходимо перекомпилировать клиентскую библиотеку со следующей командой:

    shell> ./configure --enable-thread-safe-client

Это создаст поддерживающую потоки клиентскую библиотеку `libmysqlclient_r` (предполагается, что данная операционная система включает поддерживающую потоки функцию `gethostbyname_r()`). Эта библиотека является поддерживающей потоки для данного соединения. Можно позволить двум потокам использовать одно и то же соединение со следующими оговорками:

- Два потока не могут посылать запрос серверу MySQL в одно и то же время на одном и том же соединении. В особенности необходимо быть уверенным, что в промежутках между вызовом функций `mysql_query()` и `mysql_store_result()` никакой другой поток не использует это же соединение.
- Многие потоки имеют доступ к различным результирующим наборам данных, извлекаемых функцией `mysql_store_result()`.
- При использовании функции `mysql_use_result` необходимо быть уверенным, что никакой другой поток не использует это же соединение, пока данный результирующий набор не будет обработан. Однако действительно наилучший вариант для потоковых клиентов, совместно использующих одно и то же соединение, - это применять функцию `mysql_store_result()`.
- Если необходимо использовать большое количество потоков на одном и том же соединении, то следует иметь синхронизирующую блокировку в отношении вызова комбинации функций `mysql_query()` и `mysql_store_result()`. Как только выполнение функции `mysql_store_result()` заканчивается, данная блокировка может сниматься и другие потоки могут запрашивать это же самое соединение.
- Если вы программируете с использованием потоков `POSIX`, то можно использовать функции `pthread_mutex_lock()` и `pthread_mutex_unlock()` для установки и освобождения синхронизирующей блокировки.

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

При вызове функций `mysql_init()` или `mysql_connect()` MySQL создаст специальные переменные для этого потока, которые (среди прочих применений) используются библиотекой отладки.

При вызове функции MySQL до того, как поток вызвал функции `mysql_init()` или `mysql_connect()`, данный поток в этом случае не будет иметь необходимых специальных переменных потока и, вероятно, программа рано или поздно умрет с дампом оперативной памяти.

Для более плавной работы программы необходимо выполнить следующие действия:

1. Вызвать функцию `my_init()` при запуске данной программы, если она вызывает какую-либо другую функцию MySQL до вызова функции `mysql_real_connect()`.
2. Вызвать функцию `mysql_thread_init()` в обработчике потока до вызова иной функции MySQL.
3. В данном потоке вызвать функцию `mysql_thread_end()` перед вызовом `pthread_exit()`. Это освободит память, занятую специальными переменными потока для MySQL.

Следует учитывать, что можно получить некоторые ошибки из-за наличия неопределенных символов при связывании клиента с библиотекой `libmysqlclient_r`. В большинстве случаев это происходит вследствие того, что в строку связывания/компилирования не включены библиотеки потока.

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

#### 8.4.9.1 Обзор библиотеки встраиваемого сервера MySQL

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

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

Функция | Когда вызывается
`mysql_server_init()` | Должна вызываться перед любой другой функцией MySQL, предпочтительно раньше, чем функция main().
`mysql_server_end()` | Должна вызываться перед выходом из данной программы.
`mysql_thread_init()` | Должна вызываться в каждом создаваемом потоке, который будет работать с MySQL.
`mysql_thread_end()` | Должна вызываться перед вызовом pthread_exit()

После добавления функций необходимо связать данный код с библиотекой ``libmysqld.a'` вместо ``libmysqlclient.a'`.

Вышеприведенные функции типа `mysql_server_xxx` также включены в ``libmysqlclient.a'` - таким образом обеспечивается возможность переключаться между встраиваемой и клиент-серверной версиями просто линкованием конкретного приложения с соответствующей библиотекой. См.раздел See section 8.4.5.1 `mysql_server_init()`.

#### 8.4.9.2 Компиляция программ с libmysqld

Чтобы получить библиотеку `libmysqld`, необходимо сконфигурировать (при помощи `configure`) сборку MySQL с опцией `--with-embedded-server`.

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

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

#### 8.4.9.3 Ограничения при использовании встраиваемого сервера MySQL

встраиваемый сервер имеет следующие ограничения:

- Не поддерживает таблицы `ISAM` (это сделано главным образом для уменьшения размеров библиотеки)
- Не поддерживает функции `UDF` (функции, определяемые пользователем).
- Не отслеживаются стеки на дампе оперативной памяти.
- Нет внутренней поддержки `RAID` (обычно этого не требуется, так как большинство операционных систем в настоящее время имеют поддержку для больших файлов).
- встраиваемый сервер MySQL нельзя установить как головной или подчиненный сервер репликации
- К встраиваемому серверу нельзя подсоединиться из внешнего процесса через сокеты или по протоколу TCP/IP.

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

#### 8.4.9.4 Использование файлов опций с встраиваемым сервером

Ниже приводятся рекомендации по использованию файлов опций для облегчения перехода между клиент-серверным приложением и приложением с встраиваемым MySQL (see section 4.1.2 Файлы параметров ``my.cnf'`).

- Следует помещать общие опции в раздел `[server]`. Они будут читаться обеими версиями MySQL.
- Следует помещать специфические клиент-серверные опции в раздел `[mysqld]`.
- Следует помещать специфические опции встраиваемого MySQL в раздел `[embedded]`.
- Следует помещать специфические опции приложения в раздел `[ApplicationName_SERVER]`.

#### 8.4.9.5 Что осталось сделать по встраиваемомуому серверу (TODO)

- Предполагается обеспечить возможность не включать некоторые части MySQL, чтобы сделать библиотеку меньше.
- Многое еще нужно сделать для оптимизации скорости.
- Ошибки записываются в `stderr`. Предполагается добавить возможность указывать для них имя файла.
- Необходимо изменить InnoDB, чтобы вывод этого обработчика не был бы настолько подробным во встраиваемой версии.

#### 8.4.9.6 Пример простого встраиваемого сервера

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

Чтобы запустить этот пример, создайте каталог ``test_libmysqld'` там же, где находится каталог исходного кода mysql-4.0. Сохраните исходный код ``test_libmysqld.c'` и ``GNUmakefile'` в данном каталоге и запустите GNU ``make'` в каталоге ``test_libmysqld'`.

``test_libmysqld.c'`

    /*
    * Клиент простого примера с использованием библиотеки встраиваемого
    сервера MySQL
    */
    #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[] = {
        "test_libmysqld_SERVER", "embedded", "server", NULL
    };

    int
    main(int argc, char **argv)
    {
      MYSQL *one, *two;
      /* Функцию mysql_server_init() необходимо вызывать перед любыми другими *
      функциями mysql.
      * Можно задать mysql_server_init(0, NULL, NULL); тогда для
      * инициализации сервера будут использоваться группы "server",
      * "embedded", NULL
      *}.
      *
      * В файле $HOME/.my.cnf можно указать:

    [test_libmysqld_SERVER]
    language = /path/to/source/of/mysql/sql/share/english

    * Можно было бы, конечно, модифицировать argc и argv непосредственно
      * перед передачей их в эту функцию или создать
      * новые аргументы - для этого годится любой выбранный вами способ.
      * Однако все аргументы в argv (кроме argv[0], который
      * представляет собой имя программы) должны быть допустимыми опциями
      * для сервера MySQL.
      *
      * Если данный клиент линкуется с нормальной библиотекой mysqlclient,
      * то эта функция является просто заглушкой, ничего не делающей.
      */

    mysql_server_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);

    /* Эта функция должна вызываться после всех других функций mysql */

    mysql_server_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");

    /*
    * Обратите внимание: клиент и сервер используют разные имена групп.
    * Это обязательное условие, поскольку сервер не должен использовать опции
    * клиента и наоборот.
    */

    mysql_options(db, MYSQL_READ_DEFAULT_GROUP, "test_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);
    }
    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'`

    # Предполагается, что программное обеспечение MySQL установлено в
    #/usr/local/mysql

    inc := /usr/local/mysql/include/mysql
    lib := /usr/local/mysql/lib

    # Если программное обеспечение MySQL еще не установлено, сделайте такую
    замену:

    #inc := $(HOME)/mysql-4.0/include
    #lib := $(HOME)/mysql-4.0/libmysqld

    CC := gcc
    CPPFLAGS := -I$(inc) -D_THREAD_SAFE -D_REENTRANT
    CFLAGS := -g -W -Wall
    LDFLAGS := -static

    # Можно изменить -lmysqld на -lmysqlclient для того, чтобы использовать
    # обычную клиент-серверную библиотеку

    LDLIBS = -L$(lib) -lmysqld -lz -lm -lcrypt
    ifneq (,$(shell grep FreeBSD /COPYRIGHT 2>/dev/null))

    # Для FreeBSD

    LDFLAGS += -pthread
    else

    # Предполагается Linux

    LDLIBS += -lpthread
    endif

    # Это работает для простых однофайловых тестовых программ

    sources := $(wildcard *.c)
    objects := $(patsubst %c,%o,$(sources))
    targets := $(basename $(sources))
    all: $(targets)
    clean:
    rm -f $(targets) $(objects) *.core

#### 8.4.9.7 Лицензирование встраиваемого сервера

Исходный код MySQL подпадает под действие лицензии GNU GPL (see section H GNU General Public License). Одно из следствий этого заключается в том, что любая программа, включающая (посредством связывания с `libmysqld`) исходный код MySQL, должна выпускаться как открытое программное обеспечение (под лицензией, совместимой с GPL).

Мы стараемся всячески способствовать всем, кто распространяет открытое программное обеспечение, выпуская код под GPL или совместимой лицензией. Для тех же, кому эти условия не подходят, существует другая возможность - покупка коммерческой лицензии для кода MySQL у компании MySQL AB. Более подробная информация об этом находится в разделе See section 1.6.3 Лицензии на ПО MySQL.

## 8.5 Интерфейсы C++

MySQL Connector/C++ (или `MySQL++`) является официальным MySQL API для C++. Больше информации вы можете найти на http://www.mysql.com/products/mysql++/.

### 8.5.1 Интерфейс Borland C++

Исходный код MySQL можно скомпилировать под Windows с Borland C++ 5.02 (исходный код Windows включает в себя только проекты для Microsoft VC++, а для Borland C++ файлы проекта необходимо сделать самостоятельно).

Одна известная проблема, связанная с Borland C++, заключается в том, что в нем применяется иное, чем в VC++, упорядочивание структур. Это означает, что при попытке использовать имеющуюся по умолчанию библиотеку ``libmysql.dll'` (которая была скомпилирована с VC++) совместно с Borland C++ вы столкнетесь с проблемами. Избежать этих проблем можно одним из следующих способов.

- Можно использовать статические библиотеки MySQL для Borland C++, которые находятся на http://www.mysql.com/downloads/os-win32.html.
- Вызывать функцию `mysql_init()` только с аргументом `NULL`, не выделяя предварительно структуру MYSQL.

## 8.6 Взаимодействие MySQL и Java (JDBC)

Имеется два поддерживаемых драйвера JDBC для MySQL (драйвер Connector/J и драйвер Reisin JDBC). Копию драйвера Connector/J можно найти на http://www.mysql.com/products/connector-j/, а драйвера Reisin - на http://www.caucho.com/projects/jdbc-mysql/index.xtp. По вопросам, касающимся документации, обращайтесь к любой документации по JDBC, а по вопросам, касающимся присущих MySQL специфических особенностей, - к собственной документации по конкретному драйверу.

## 8.7 Интерфейсы Python API для MySQL

MySQLdb предоставляет поддержку MySQL для Python, в соответствии с интерфейсом баз данных, принятом в Python (Python DB API). Вы можете найти его здесь: http://sourceforge.net/projects/mysql-python/.

## 8.8 Интерфейсы Tcl API для MySQL

MySQLtcl - это простой API для доступа к базам данным MySQL при помощи Tcl. Вы можете найти его здесь: http://www.xdobry.de/mysqltcl/.

## 8.9 Оболочка Eiffel для MySQL

Eiffel MySQL - это интерфейс к базам данным MySQL для языка Eiffel, написанный Майклом Рэвитсом (Michael Ravits). Вы можете найти его здесь: http://efsa.sourceforge.net/archive/ravits/mysql.htm.

Go to the first, previous, next, last section, table of contents.