Есть два способа обращения из программы на perl к базе данных MySQL. Дело в том, что два разных человека написали в общем-то одинаково хорошие, хотя и разные библиотеки для такого доступа. Решено включить в поставку оба варианта perl API.
Наличие perl API дает огромные возможности по доступу к базам данных MySQL из скриптов на этом языке. Учитывая, что perl очень часто используется в интернете (для написания CGI-скриптов), этот интерфейс позволяет создавать web-ориентированные базы данных.
Этот интерфейс представляет собой первый способ обратиться к базе данных 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.
Вы будете иметь дело с двумя классами: < tt> Mysql::Statement< /tt> работаете с ним через операторный дескриптор, возвращенный командами Query или ListFields. Единственный класс, который Вы называете явно - Mysql. Это предоставляет Вам команду Connect.
Из-за ограничений perl по обработке числовых значений, Вы будете иметь проблемы при использовании чисел больше чем signed LONG (2147483647). Это может происходить при использовании в MySQL типов данных unsigned LONG (DOUBLE) или LONGLONG (BIGINT). Perl хранит возвращаемые значения как строки, но автоматически преобразуют их в числа, когда Вы используете значения в числовом контексте. Это их усечет до 2147483647, так как perl использует тип signed LONG, чтобы хранить такие числа.
Вы можете использовать один способ это обойти. Прежде всего всегда обрабатывайте значения, которые могут быть ОЧЕНЬ большими, как строки, а не как числа. Пока Вы делаете это, они могут отображаться и заново вставляться в базу данных без инцидентов. То же самое можно посоветовать для вставки новых значений в таблицы. Если Вы устанавливаете переменную, названную $tmpvar, равную "4147483647" и затем выполняете INSERT, чтобы вставить ее в базу данных, все будет нормально. Обратите внимание, что кавычки здесь очень важны, так как они заставляют perl обрабатывать значение как строку.
Если Вы должны делать вычисления, включающие большие числа, то их нужно выполнять через начальный SELECT.
Эта команда устанавливает соединение с сервером и базой данных. Без аргумента или с пустой строкой в качестве первого аргумента он связывается с устройством UNIX /dev/mysql, который сильно повышает эффективность. Имя базы данных во втором аргументе указывает с какой именно базой данных надо связаться. Возвращается дескриптор базы данных, если команда Connect выполнена успешно. В противном случае возвращаемое значение не определено. Если Вы используете mysqld, скомпилированный с библиотекой потоков MIT, Вы не сможете использовать устройства. В этом случае укажите имя сервера в переменной host. А вообще библиотека потоков MIT такое глюкало...
Можно указать имя пользователя и пароль. Если имя пользователя не указано, используется текущий логин. Если не указан пароль, а пользователь его имеет, связь установить не получится.
Возвращаемый дескриптор нужен для обращения к базе данных. Можно отдать несколько команд Connect переменных ($dbh1,$dbh2, $dbh3, ...)
Из полученного дескриптора можно извлечь сведения о имени сервера, порте и имени базы данных:
$scalar = $dbh->sock;
$scalar = $dbh->host;
$scalar = $dbh->database;
Имя базы данных не определено, если при вызове команды Connect было указано только имя сервера.
$ENV{"MYSQL_TCP_PORT"}=3334;
$ENV{"MYSQL_UNIX_PORT"}="/tmp/mysql_new.sock";
use Mysql;
$dbh = Mysql->Connect($host);
Выбор базы данных для использования.
СИНТАКСИС:
$dbh->SelectDB($database);
ОПИСАНИЕ:
Если база данных не выбрана в команде Connect, или если нужно связаться с другой базой данных, то используется дескриптор базы данных из предыдущего вызова команды Connect. Он используется командой SelectDB.
Список полей в таблице.
СИНТАКСИС:
$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 |
Выполнить запрос.
СИНТАКСИС:
ОПИСАНИЕ:
Эта функция позволяет Вам посылать запрос базе данных. Вы должны использовать 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 возвращает массив, который содержит один элемент для имени каждой базы данных, управляемой MySQL.
ПРИМЕР:
@dbs = $dbh->ListDBs; # Возвращает массив имен баз данных. $count = $#dbs; # Вычисляет сколько элементов. for ($i=0;$i<=$count;$i++) { print(" ".$dbs[$i]."\n"); }
Список таблиц, доступных в базе данных.
СИНТАКСИС:
@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"); }
Возвращает массив, содержащий один столбец, состоящий из значений.
СИНТАКСИС:
@arr = $sth->FetchCol($col);
ОПИСАНИЕ:
Возвращает массив значений для столбца номер $col. FetchRow возвращает следующую строку результата запроса. FetchCol возвращает весь одиночный столбец результата запроса.
Обратите внимание, что эта функция сбросит текущий указатель строки на конец таблицы; вы должны использовать DataSeek(0), чтобы переустановить его.
Возвращает результат запроса.
СИНТАКСИС:
ОПИСАНИЕ:
Возвращает ассоциативный массив, содержащий следующую строку, полученную с сервера.
Возвращает строку результатов.
СИНТАКСИС:
@arr = $sth->FetchRow;
ОПИСАНИЕ:
Возвращает массив значений следующей строки, полученной с сервера.
Позиционируется на произвольную позицию в данных.
СИНТАКСИС:
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 может быть очень полезной в случае проблем с отладкой. Если Вы вызываете программу на perl с опцией -w, то предупреждения, обычно хранимые в $Mysql::db_errstr будут выводиться в STDERR (стандартный поток ошибок). Таким образом, Вы получите сообщения об ошибках сервера MySQL без обработки их в Вашей программе.
Если надо использовать опцию -w, но не надо, чтобы сообщения об ошибках увидел демон MySQL, можно установить переменную $Mysql::QUIET в любое ненулевое значение.
MySQL использует библиотеку libmysql.a, написанную Михаэлем Видениусом (Michael Widenius). Эта библиотека обязательно должна быть установлена до использования этого интерфейса с 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