Портал для веб-мастера
Вход пользователей
Поиск статей
WoWeb.ru » Статьи » Программирование для Web » PERL/CGI

Работа с базами данных из Perl. Краткое введение в DBI.

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

Для этих целей в Perl существует множество различных модулей, которые оптимизованы для работы с конкретными типами баз данных. Но как правило эти модули имеют разные наборы функций для работы с базами. Для упрощения переноса приложений был разработан модуль DBI. Он построен по модульной архитектуре -- для каждой СУБД существует драйвер, реализующий специфику работы с конкретной базой данных. Сначала мы рассмотрим основные функции работы с базами данных, а затем перейдем к практическому примеру применения DBI.

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

  1. Подключение к базе данных с помощью функции connect
  2. Подготовка запроса к выполнению с помощью функции prepare
  3. Выполнение запроса с помощью функции execute
  4. Выборка данных (для запросов содержащих команду SQL select) с помощью функций fetch
  5. Завершение работы с базой данных -- функции finish и disconnect

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

Для работы необходимо подключить модуль DBI к вашему скрипту. Это осуществляется с помощью директивы use DBI.

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

my $dbh=DBI->connect("dbi:Pg:dbname=dbase;host=localhost;port=5432", "user","pass"); 

В данном примере производится подключение к базе dbase при помощи драйвера PostgreSQL. Подключение производится под именем пользователя user с паролем pass. При удачном подключении функция возвращает дескриптор базы данных, который часто обозначают как $dbh. Дальнейшая работа с базой данных осуществляется через этот дескриптор.

Выполнение SQL-выражений

Для выполнения SQL-выражений в DBI существует два метода -- использование цепочки prepare, execute; и функция do.

Функция do в основном используется для выполнения выражений, не возвращающих наборов данных, такие как insert, update и delete. В качестве результата возвращается количество строк, затронутых данным выражением. Данная функция применяется к дескриптору базы данных. Вот пример использования:

$rv = $dbh->do("delete from test1 where id <20"); 

Набор функций prepare, execute чаще используется для выполнения выражений select, которые возвращают наборы данных. Для начала работы необходимо создать с помощью функции prepare дескриптор выражения. Данный дескриптор можно использовать для выполнения выражения с разными данными. Выполнение самого выражения производится с помощью функции execute для дескриптора выражения. При выполнении этой функции, параметры, обозначенные в SQL-выражении знаком вопроса ?, заменяются на параметры, переданные функции execute. При успешном выполнении функции возвращается истинное значение. После выполнения функции можно получать данные.

Получение результатов

После выполнения SQL-выражения мы можем получать не только данные, но и некоторую информацию о выполненном запросе. Некоторые драйвера поддерживают функцию row, которая возвращает количество строк, извлеченных запросом. Можно также получить информацию о типе и длине полей строк, возвращаемых после выполнения запроса.

Для получения строки данных может использоваться функция fetchrow_array, которая возвращает список, состоящий из данных возвращенных SQL-выражением. Альтернативами данной функции могут быть функции fetchrow_arrayref и fetchrow_hashref, которые возвращают ссылки на массив или ассоциативный массив, хранящий результаты. При использовании ассоциативного списка, выполняется дополнительная работа по созданию пар "ИМЯ ПОЛЯ=ЗНАЧЕНИЕ".

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

Транзакции

Вы можете явно управлять транзакциями с помощью функций DBI. По умолчанию действует режим, когда все действия автоматически подтверждаются. Функция begin_work начинает новую транзакцию, отключая режим автоматического подтверждения выражений. Если драйвер не поддерживает концепцию транзакций, то возвращается ошибка. Функции commit и rollback соответственно подтверждают или отменяют выполненные выражения. Все эти функции применяются к дескриптору базы данных.

Завершение работы

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

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

Практический пример

Давайте рассмотрим процедуру, которая производит извлечение ленты новостей из базы данных. Новости хранятся в базе данных news и разбиты на несколько категорий, список которых хранится в другой таблице. Кроме этого производится доступ к таблице users, хранящей данные о пользователях, которые помещают новости. Новости разбиваются на страницы по 20 новостей на страницу.

Вот полный текст процедуры, который будет описан далее:

 1	sub BuildNewsPage { 2	 my ($cat,$id)=@_; 3	 my %params; 4	 my $dbh = DBI->connect("dbi:Pg:dbname=news;host=localhost;port=5432", 5			 "news", "test", { RaiseError => 0, AutoCommit => 1 }); 6	 if (!defined($dbh)) { 7	 $params{Error}='Hе могу откpыть базу данных'; 8	 } else { 9	 my $where="and catid="; 10	 my $cattext=""; 11	 my %cats=GetNewsCategories($r); 12	 $cat='1' if !defined($cat); 13	 if (defined($cat)) { 14	 $where.=$cat; 15	 $cattext=$cats{$cat}->{title}; 16	 } 17	 if (lc($cat) eq 'all'){ 18	 $where=""; 19	 $cattext="Все новости"; 20	 } 21	 $where.="and n.id < $id" if defined($id); 22	 my $sql="select n.id, data::date, n.sender, u.fullname, n.news, \ 23	 n.moreinfo from news n, users u where n.sender=u.login \ 24	 $where order by n.id desc limit 20"; 25	 my $sth = $dbh->prepare($sql); 26	 if ( !defined($sth) ) { 27	 $params{Error}='Hе могу выполнить запpос к базе новостей'; 28	 } else { 29	 $sth->execute(); 30	 my @news=(); 31	 while (my ($id, $data, $login, $sender, $news, $moreinfo) = $sth->fetchrow_array()) { 32		my %t1; 33		$t1{sender}=$sender; 34		$t1{login}=$login; 35		$t1{id}=$id; 36		$t1{newstitle}=$news; 37		$t1{newsbody}=$moreinfo; 38		$t1{date}=$data; 39		push @news,\%t1; 40	 } 41	 $sth->finish(); 42	 $dbh->disconnect if defined($dbh); 43 $params{news}=\@news; 44	 } 45	 } 46	 return %params ; 47	} 

Процедуре передается два параметра $cat -- категория новостей и $id -- идентификатор новости с которой надо начать выборку (в том случае, если мы показываем вторую и последующие страницу новостей. Хеш %params будет хранить в себе сообщения об ошибках и данные, для заполнения шаблона страницы.

В строках 4-7 мы подключаемся к базе данных PostgreSQL (драйвер базы данных называется Pg) и выполняется проверка того, как произошло подключение. Если произошла ошибка подключения, то мы помещаем соответствующее сообщение в хеш %params. Сообщения об ошибках выдаются вызывающей процедурой, которая также заполняет шаблон страницы.

В строках 9-21 формируется условие для SQL выражения, которое ограничивает набор отображаемых новостей. Если номер категории не задан, то отображаются новости категории 1 (главные новости).

Затем в строках 22-27 формируется текст запроса и выполняется подготовка к выполнению запроса. Если функция prepare возвратит неопределенное значение, то мы сообщаем об ошибке (строки 26-27).

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

После извлечения всех новостей, запрос закрывается и производится отключение от базы данных (строки 41-42). И в заключение сформированный хеш с результатами работы возвращается вызывающей программе, которая производит формирование страницы для пользователя.

Заключение

Самой лучшей документацией по модулю DBI является его справочная страница доступная с помощью программ perldoc и man. Также на русский язык переведена книга Perl DBI Programming. Кроме описания работы с модулем DBI, данная книга представляет краткое введение в язык структурированных запросов SQL, а также описание других методов хранения информации, возможных при работе с Perl.

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

Автор: Alex Ott · Добавлена: 2003-10-11
Источник статьи · Просмотров: 3012 · Рейтинг: 3.0

Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Категории раздела
Flash
Apache
WWW
PhotoShop
Веб-дизайн
Раскрутка и реклама
Базы данных
3D графика
Хостинг
Истории веб-мастеров
Web-технологии
Сетевая безопасность
Программирование для Web
Операционные системы

Новые статьи
Лучшие статьи
Популярные статьи
Комментируемые статьи
Разделы сайта
Скрипты
Статьи
Шрифты
Флэш исходники
HTML шаблоны
Партнерки
Клипарты
Смайлы
Фоны
Гифы
Иконки
Опрос сайта
Есть ли у вас свой сайт?
Всего ответов: 140571
Наша кнопка
WoWeb.ru - портал для веб-мастера