Интерфейс с perl (MySQL perl API)


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

Есть два способа обращения из программы на perl к базе данных MySQL. Дело в том, что два разных человека написали в общем-то одинаково хорошие, хотя и разные библиотеки для такого доступа. Решено включить в поставку оба варианта perl API.

Наличие perl API дает огромные возможности по доступу к базам данных MySQL из скриптов на этом языке. Учитывая, что perl очень часто используется в интернете (для написания CGI-скриптов), этот интерфейс позволяет создавать web-ориентированные базы данных.

Простой интерфейс с perl СУБД MySQL

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

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

  use Mysql;

  $dbh = Mysql->Connect;
  $dbh = Mysql->Connect($host);
  $dbh = Mysql->Connect($host,$database);
  $dbh = Mysql->Connect($host,$database,$password);
  $dbh = Mysql->Connect($host,$database,$password,$user);
  $dbh->SelectDB($database);

  $sth = $dbh->ListFields($table);
     @arr = @{$sth->name};
     @arr = @{$sth->length};
     $value = $sth->numfields;
     @arr = @{$sth->type};
     @arr = @{$sth->is_num};
     @arr = @{$sth->is_blob};
     @arr = @{$sth->is_not_null};

  $sth = $dbh->Query($sql_statement);
  @arr = $dbh->ListDBs;
  @arr = $dbh->ListTables;
  @arr = $sth->FetchRow;
  %hash = FetchHash $sth;
  $sth->DataSeek($row_number);
  $scalar = $dbh->sock;
  $scalar = $dbh->host;
  $scalar = $dbh->database;
  $scalar = $dbh->quote($binary_string);

Ну что, всем все ясно? Кому еще не ясно, объясняю.

При разработке этого пакета, его старались сделать как можно более похожим на C API.

Вы будете иметь дело с двумя классами: Mysql::Statement работаете с ним через операторный дескриптор, возвращенный командами Query или ListFields. Единственный класс, который Вы называете явно - Mysql. Это предоставляет Вам команду Connect.

Очень большие числа

Из-за ограничений perl по обработке числовых значений, Вы будете иметь проблемы при использовании чисел больше чем signed LONG (2147483647). Это может происходить при использовании в MySQL типов данных unsigned LONG (DOUBLE) или LONGLONG (BIGINT). Perl хранит возвращаемые значения как строки, но автоматически преобразуют их в числа, когда Вы используете значения в числовом контексте. Это их усечет до 2147483647, так как perl использует тип signed LONG, чтобы хранить такие числа.

Вы можете использовать один способ это обойти. Прежде всего всегда обрабатывайте значения, которые могут быть ОЧЕНЬ большими, как строки, а не как числа. Пока Вы делаете это, они могут отображаться и заново вставляться в базу данных без инцидентов. То же самое можно посоветовать для вставки новых значений в таблицы. Если Вы устанавливаете переменную, названную $tmpvar, равную "4147483647" и затем выполняете INSERT, чтобы вставить ее в базу данных, все будет нормально. Обратите внимание, что кавычки здесь очень важны, так как они заставляют perl обрабатывать значение как строку.

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


Connect

$dbh = Mysql->Connect;
$dbh = Mysql->Connect($host);
$dbh = Mysql->Connect($host,$database);
$dbh = Mysql->Connect($host,$database,$password);
$dbh = Mysql->Connect($host,$database,$password,$user);

Эта команда устанавливает соединение с сервером и базой данных. Без аргумента или с пустой строкой в качестве первого аргумента он связывается с устройством UNIX /dev/mysql, который сильно повышает эффективность. Имя базы данных во втором аргументе указывает с какой именно базой данных надо связаться. Возвращается дескриптор базы данных, если команда Connect выполнена успешно. В противном случае возвращаемое значение не определено. Если Вы используете mysqld, скомпилированный с библиотекой потоков MIT, Вы не сможете использовать устройства. В этом случае укажите имя сервера в переменной host. А вообще библиотека потоков MIT такое глюкало...

Можно указать имя пользователя и пароль. Если имя пользователя не указано, используется текущий логин. Если не указан пароль, а пользователь его имеет, связь установить не получится.

Возвращаемый дескриптор нужен для обращения к базе данных. Можно отдать несколько команд Connect переменных ($dbh1,$dbh2, $dbh3, ...)

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

$scalar = $dbh->sock;
$scalar = $dbh->host;
$scalar = $dbh->database;

Имя базы данных не определено, если при вызове команды Connect было указано только имя сервера.

Смена порта

Сменить порт, к которому присоединился MysqlPerl можно так:

$ENV{"MYSQL_TCP_PORT"}=3334;
$ENV{"MYSQL_UNIX_PORT"}="/tmp/mysql_new.sock";
use Mysql;
$dbh = Mysql->Connect($host);


SelectDB

Выбор базы данных для использования.

СИНТАКСИС:

$dbh->SelectDB($database);

ОПИСАНИЕ:

Если база данных не выбрана в команде Connect, или если нужно связаться с другой базой данных, то используется дескриптор базы данных из предыдущего вызова команды Connect. Он используется командой SelectDB.


ListFields

Список полей в таблице.

СИНТАКСИС:

$sth = ListFields $dbh $table;

ОПИСАНИЕ:

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

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

Перед использованием следующих функций, Вы должны выполнить успешное обращение к ListFields.

@arr = @{$sth->name}; Возвращает массив имен столбцов
@arr = @{$sth->length}; Возвращает массив длин столбцов
$value = $sth->numfields; Возвращает количество столбцов в таблице
@arr = @{$sth->type}; Массив MySQL типов
@arr = @{$sth->is_num}; Массив 0 и 1, где 1 указывает что столбец числовой
@arr = @{$sth->is_blob}; Массив 0 и 1, где 1 указывает что столбец - blob
@arr = @{$sth->is_not_null}; Массив 0 и 1, где 1 указывает что столбец - не NULL


Query

Выполнить запрос.

СИНТАКСИС:

ОПИСАНИЕ:

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

ПРИМЕР:

  $sth = $dbh->Query("SELECT * FROM Widget_Table
                        WHERE widget_id = 1") or die $Mysql::db_errstr;

    $foo = $record[0];
    $bar = $record[1];
  }

Хорошая идея - всегда проверить ошибки. В этом примере такой проверкой занимается блок "or die..." оператора Query.


ListDBs

Список доступных баз данных.

СИНТАКСИС:

ОПИСАНИЕ:

ListDBs возвращает массив, который содержит один элемент для имени каждой базы данных, управляемой MySQL.

ПРИМЕР:

  @dbs = $dbh->ListDBs; # Возвращает массив имен баз данных.
  $count = $#dbs;          # Вычисляет сколько элементов.
  for ($i=0;$i<=$count;$i++) {
    print("   ".$dbs[$i]."\n");
  }


ListTables

Список таблиц, доступных в базе данных.

СИНТАКСИС:

@arr = $dbh->ListTables;

ОПИСАНИЕ:

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

ПРИМЕР:

  @tables = $dbh->ListTables;    # Assumes that $dbh points
                                    # to a valid database
  $count = $#tables;                # Figure out how many elements.
  for ($i=0;$i<=$count;$i++) {   # Print out the table names.
    print("   ".$tables[$i]."\n");
  }

FetchCol

Возвращает массив, содержащий один столбец, состоящий из значений.

СИНТАКСИС:

@arr = $sth->FetchCol($col);

ОПИСАНИЕ:

Возвращает массив значений для столбца номер $col. FetchRow возвращает следующую строку результата запроса. FetchCol возвращает весь одиночный столбец результата запроса.

Обратите внимание, что эта функция сбросит текущий указатель строки на конец таблицы; вы должны использовать DataSeek(0), чтобы переустановить его.


FetchHash

Возвращает результат запроса.

СИНТАКСИС:

ОПИСАНИЕ:

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


FetchRow

Возвращает строку результатов.

СИНТАКСИС:

@arr = $sth->FetchRow;

ОПИСАНИЕ:

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


DataSeek

Позиционируется на произвольную позицию в данных.

СИНТАКСИС:

DataSeek $sth $row_number;

ОПИСАНИЕ:

Дает возможность Вам определить смещение в данных, связанное с операторным дескриптором. Следующий вызов FetchRow возвратит соответствующую строку (первая строка имеет смещение = 0).


Обработка двоичных строк

Некоторых символов нужно избежать прежде, чем двоичные строки могут быть вставлены в базу данных MySQL. MySQL perl API обеспечивает следующую функцию, чтобы делать это автоматически.

СИНТАКСИС:

$scaler = $dbh->quote($binary_string)

ОПИСАНИЕ:

Конвертирует строку: пропускает все символы ' и \, а также конвертирует \0 и \n.


Потерянные значения

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


Метаданные

Теперь пересмотрим вышеупомянутые методы в отношении метаданных.

Дескриптор базы данных

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

$dbh = Connect Mysql $host, $database;

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

$scalar = $dbh->sock;
$scalar = $dbh->host;
$scalar = $dbh->database;

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


Операторный дескриптор

Два конструктора возвращают операторный дескриптор:

$sth = ListFields $dbh $table;
$sth = Query $dbh $sql_statement;

$sth хранит все метаданные, предоставляемые API:

$scalar = $sth->affected_rows; Сколько записей вставлено или изменено.
$scalar = $sth->info; Статистика о предыдущих запросах ALTER TABLE или LOAD DATA FROM INFILE.
$arrref = $sth->is_blob; Массив битов, специфицирующих является ли данное поле BLOB.
$arrref = $sth->is_not_null; Массив битов, специфицирующих является ли данное поле NULL.
$arrref = $sth->is_pri_key; Массив битов, специфицирующих является ли данное поле первичным ключом.
$arrref = $sth->is_num; Массив битов, специфицирующих является ли данное поле числом.
$scalar = $sth->insert_id; Значение, присвоенное столбцу с помощью AUTO_INCREMENT последним INSERT.
$arrref = $sth->length; Массив длин всех полей в байтах.
$arrref = $sth->name; Имена всех столбцов.
$scalar = $sth->numrows; Количество возвращаемых записей.
$scalar = $sth->numfields; Количество возвращаемых полей.
$arrref = $sth->table; Имена каждого столбца в таблице.
$arrref = $sth->type; Тип каждого столбца, определен в mysql.h. Доступен с помощью &Mysql::CHAR_TYPE, &Mysql::INT_TYPE, &Mysql::REAL_TYPE


Опция -w

Опция -w может быть очень полезной в случае проблем с отладкой. Если Вы вызываете программу на perl с опцией -w, то предупреждения, обычно хранимые в $Mysql::db_errstr будут выводиться в STDERR (стандартный поток ошибок). Таким образом, Вы получите сообщения об ошибках сервера MySQL без обработки их в Вашей программе.

Если надо использовать опцию -w, но не надо, чтобы сообщения об ошибках увидел демон MySQL, можно установить переменную $Mysql::QUIET в любое ненулевое значение.

Предупреждение

MySQL использует библиотеку libmysql.a, написанную Михаэлем Видениусом (Michael Widenius). Эта библиотека обязательно должна быть установлена до использования этого интерфейса с perl.

Об авторе интерфейса

MySQL perl API основан на mSQL perl API версии 1.17, разработанной Андреасом Коенигом (Andreas Koenig's koenig@franz.ww.TU-Berlin.DE).


Драйвер MySQL DBD Perl

Этот драйвер представляет собой второй способ обратиться к базе данных MySQL из программы на perl.

В настоящее время эта часть описания интерфейса с perl только немного переработана, относительно версии стандартной pod-документации. Данная часть описания изготовлена с помощью команды pod2html -mke.

Обзор:


  use DBI;

  $dbh = DBI->connect( $host, $database, $user, 'mysql' [, $password] );
  # or
  $dbh = DBI->connect('', '', '', 'mysql', {hostname => "localhost",
                      port => 3333, database => "test",
                      username => "myname", password => "mypassword",});

ПРИМЕР:


#!/usr/bin/perl

use DBI;

$drh = DBI->install_driver('mysql');
$dbh = $drh->connect('','test','','') or die "Error connecting to database";
$dbh->do("DROP TABLE foo");
$dbh->do("CREATE TABLE foo ( Field_1 VARCHAR(60) )");
$count = 1;

while ($count < 500) {
  $sth = $dbh->prepare("INSERT INTO foo VALUES('XXXYYYZZZ')");
  $sth->execute;
  $sth->finish; # Очень важно вызвать finish, иначе не освободится память.
  print "$count\n" unless $count % 10;
  $count = $count + 1;
}

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

DBD::mysql является драйвером для работы с базой данных, управляемой СУБД MySQL. Он портирован Michael 'Monty' Widenius of Alligator Descartes' DBD::msql. Вы должны установить DBI-модуль перед использованием DBD::mysql.

$host может быть просто именем сервера (``up.botik.ru'') или именем сервера с указанием порта (``up.botik.ru:3333'').

$database задает имя базы данных с которой надо связаться.

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

$password является опциональным и нужно только для аккаунтов, которые имеют не пустые пароли.

Системные переменные, которые использует DBD::mysql:

Значения в системных переменных отменяют значения, переданные раньше. TCP номер порта, отменяет TCP номер порта, переданный в hostname.

Можно разрешить отладку, установив переменную MYSQL_DEBUG 'd:t:O,filename' (где filename является именем файла для записи протокола). Протокол будет записан в файл только если libmysql откомпилирована с поддержкой отладки (опция DBUG).

Поддерживаются следующие тэги:

Для получения значения поля AUTO_INCREMENT INSERT, надо:

  $id = $dbh->func("_InsertID");

Очень большие числа

Ограничения на работу с ОЧЕНЬ БОЛЬШИМИ числами специфичны для языка perl вообще, а не для какого-либо API в частности. Так что все, что об этом сказано выше, справедливо и в данном случае.

Вставка двоичных строк

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

  $mystring = $dbh->quote($rawstring);

Об авторе интерфейса

Msqlperl разработан (C)1997 Alligator Descartes. Модифицирован Msqlperl by Michael 'Monty' Widenius. Все изменения доступны на условиях public domain. Pod-документация, на которой основана данная глава, и _InsertID

Что можно почитать

DBI(3) для информации об использовании DBD/DBI.
http://www.hermetica.com/technologia/perl/DBI домашняя страничка DBI,
http://www.tcx.se домашняя страничка mysql,
www.hughes.com.au домашняя страничка msql.

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

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

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

© 2000 Alexey Pautov rldp@ftp.botik.ru.
Information Club of the developers PHP