Подключение к базе данных в Perl

В этой главе мы познакомим вас с подключениями к базам данных Perl.

В Perl 5 мы можем использовать модуль DBI для подключения к базам данных.

Полное английское название DBI — Database Independent Interface, по-китайски известное как интерфейс, независимый от базы данных.

Как стандартный интерфейс для связи между языком Perl и базами данных, DBI определяет ряд методов, переменных и констант, обеспечивая уровень персистентности базы данных, независимый от какой-либо конкретной платформы баз данных.


Структура DBI

DBI не зависит от конкретных платформ баз данных, и мы можем применять его к таким базам данных, как Oracle, MySQL или Informix.

На диаграмме DBI получает все SQL-данные, отправленные из API (интерфейс прикладного программирования), распределяет их по соответствующим драйверам для выполнения и в конечном итоге извлекает и возвращает данные.

Соглашения об именовании переменных

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

$dsn    驱动程序对象的句柄
$dbh    一个数据库对象的句柄
$sth    一个语句或者一个查询对象的句柄
$h      通用的句柄 ($dbh, $sth, или  $drh),依赖于上下文
$rc     操作代码返回的布什值(true или  false)
$rv     操作代码返回的整数值
@ary    查询返回的一行值的数组(列表)
$rows   操作代码返回的行数值
$fh     文件句柄
undef   NULL 值表示未定义
\%attr  引用属性的哈希值并传到方法上

Подключение к базе данных

Далее мы на примере базы данных MySQL покажем, как Perl выполняет операции с базой данных.

Здесь мы создаём базу данных EXAMPLE в MySQL с таблицей данных Websites. Структура таблицы и данные показаны на рисунке ниже:

Скачать эту таблицу данных:/static.jyshare.com/download/websites_perl.sql

Далее мы используем следующий код для подключения к базе данных:

Пример

#!/usr/bin/perl -w use strict; use DBI; my $host = "localhost"; # Адрес хоста my $driver = "mysql"; # Тип интерфейса, по умолчанию localhost my $database = "EXAMPLE"; # База данных # Дескриптор объекта драйвера my $dsn = "DBI:$driver:database=$database:$host"; my $userid = "root"; # Имя пользователя базы данных my $password = "123456"; # Пароль базы данных # Подключиться к базе данных my $dbh = DBI->connect($dsn, $userid, $password ) or die $DBI::errstr; my $sth = $dbh->prepare("SELECT * FROM Websites"); # Подготовить SQL-запрос $sth->execute(); # Выполнить SQL-операцию # В закомментированной части используются операции привязки значений # $alexa = 20; # my $sth = $dbh->prepare("SELECT name, url # FROM Websites # WHERE alexa > ?"); # $sth->execute( $alexa ) or die $DBI::errstr; # Перебрать и вывести все данные while ( my @row = $sth->fetchrow_array() ) { print join('\t', @row)."\n"; } $sth->finish(); $dbh->disconnect();

Операция вставки

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

  • Используйте API prepare() для подготовки SQL-запроса.
  • Используйте API execute() для выполнения SQL-запроса.
  • Используйте API finish() для освобождения дескриптора оператора.
  • Наконец, если всё пройдёт успешно, вышеописанные выполненные операции будут зафиксированы.
my $sth = $dbh->prepare("INSERT INTO Websites
                       (name, url, alexa, country )
                        values
                       ('Twitter', 'https://twitter.com/', 10, 'USA')");
$sth->execute() or die $DBI::errstr;
$sth->finish();
$dbh->commit or die $DBI::errstr;

Приложения также могут связывать выходные и входные параметры. В следующем примере выполняется запрос на вставку путём замены заполнителей ? переменными:

my $name = "Twitter";
my $url = "https://twitter.com/";
my $alexa = 10;
my $country = "USA";
my $sth = $dbh->prepare("INSERT INTO Websites
                       (name, url, alexa, country )
                        values
                       (?,?,?,?)");
$sth->execute($name,$url,$alexa, $country) 
          or die $DBI::errstr;
$sth->finish();
$dbh->commit or die $DBI::errstr;

Операция обновления

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

  • Используйте API prepare() для подготовки SQL-запроса.
  • Используйте API execute() для выполнения SQL-запроса.
  • Используйте API finish() для освобождения дескриптора оператора.
  • Наконец, если всё пройдёт успешно, вышеописанные выполненные операции будут зафиксированы.
my $sth = $dbh->prepare("UPDATE Websites
                        SET   alexa = alexa + 1 
                        WHERE country = 'CN'");
$sth->execute() or die $DBI::errstr;
print "更新的记录数 :" + $sth->rows;
$sth->finish();
$dbh->commit or die $DBI::errstr;

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

$name = 'Example';

my $sth = $dbh->prepare("UPDATE Websites
                        SET   alexa = alexa + 1 
                        WHERE name = ?");
$sth->execute('$name') or die $DBI::errstr;
print "更新的记录数 :" + $sth->rows;
$sth->finish();

Конечно, мы также можем связать значения, которые нужно установить, как показано ниже, изменив alexa всех записей со значением country CN на 1000:

$country = 'CN';
$alexa = 1000:;
my $sth = $dbh->prepare("UPDATE Websites
                        SET   alexa = ?
                        WHERE country = ?");
$sth->execute( $alexa, '$country') or die $DBI::errstr;
print "更新的记录数 :" + $sth->rows;
$sth->finish();

Удаление данных

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

  • Используйте API prepare() для подготовки SQL-запроса.
  • Используйте API execute() для выполнения SQL-запроса.
  • Используйте API finish() для освобождения дескриптора оператора.
  • Наконец, если всё пройдёт успешно, вышеописанные выполненные операции будут зафиксированы.

Следующий запрос удаляет все данные из Websites, где alexa больше 1000:

$alexa = 1000;
my $sth = $dbh->prepare("DELETE FROM Websites
                        WHERE alexa = ?");
$sth->execute( $alexa ) or die $DBI::errstr;
print "删除的记录数 :" + $sth->rows;
$sth->finish();
$dbh->commit or die $DBI::errstr;

Использование оператора do

doОператор do может выполнять операции UPDATE, INSERT или DELETE. Он краток; он возвращает true при успехе и false при неудаче. Пример выглядит следующим образом:

$dbh->do('DELETE FROM Websites WHERE alexa>1000');

Операция COMMIT

commit используется для фиксации транзакции и завершения операций с базой данных:

$dbh->commit or die $dbh->errstr;

Операция ROLLBACK

Если во время выполнения SQL возникает ошибка, можно откатить данные, не внося никаких изменений:

$dbh->rollback or die $dbh->errstr;

Транзакции

Как и другие языки, Perl DBI также поддерживает обработку транзакций для операций с базой данных. Существует два способа её реализации:

1. Начать транзакцию при подключении к базе данных

$dbh = DBI->connect($dsn, $userid, $password, {AutoCommit => 0}) or die $DBI::errstr;

Приведённый выше код устанавливает AutoCommit в false при подключении. Это означает, что при выполнении операций обновления в базе данных они не будут автоматически записываться напрямую в базу данных. Вместо этого программа должна использовать $dbh->commit, чтобы действительно записать данные в базу данных, или $dbh->rollback, чтобы откатить предыдущие операции.

2. Начать транзакцию с помощью оператора $dbh->begin_work()

Этот подход не требует установки AutoCommit = 0 при подключении к базе данных.

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

$rc  = $dbh->begin_work  or die $dbh->errstr;

#####################
##这里执行一些 SQL 操作
#####################

$dbh->commit;    # 成功后操作
-----------------------------
$dbh->rollback;  # 失败后回滚

Отключение от базы данных

Если нам нужно отключиться от базы данных, мы можем использовать API disconnect:

$rc = $dbh->disconnect  or warn $dbh->errstr;
Другие расширения