Глава 14 Базы данных

14.10. Выполнение команд SQL с помощью DBI и DBD

Проблема

Вы хотите направить запрос SQL в систему управления базами данных (например, Oracle, Sybase, mSQL или MySQL) и обработать полученные результаты.

Решение

Воспользуйтесь модулями DBI (DataBase Interface) и DBD (DataBase Driver) от CPAN:
use DBI:
$dbh = Dbl->connect('DBI:driver', 'username', 'auth',
{ PrintError => 1, RaiseError => 1})
or die "connecting: $DBI::errstr";
$dbh->do(SQL)
or die "doing: ", $dbh->errstr;
$sth = DBI->prepare(SQL)
or die "preparing: ", $dbh->errstr;
$sth->execute
or die "executing: ", $sth->errstr;
while (@)row = $sth->fetchrow_array) {
# . . .
} $sth->finish;
$dbh->disconnect;

Комментарий

DBI является посредником между программой и всеми драйверами, предназначенными для работы с конкретными СУБД. Для большинства операций нужен манипулятор базы данных (в приведенном выше примере - $dbh).0n ассоциируется с конкретной базой данных и драйвером
Первый аргумент DBI->connect представляет собой строку, состоящую из трех полей, разделенных двоеточиями. Он определяет источник данных - СУБД, к которой вы подключаетесь. Первое поле всегда содержит символы DBI, а второе - имя драйвера, который вы со Второй и третий аргументы выполняют аутентификацию пользователя. Четвертым, необязательным аргументом является ссылка на хэш с определением <>трибутов подключения. Если атрибут PrintError равен true, при каждом неудачном вызове метода DBI будет выдавать п
Простые команды SQL (но возвращающие записи данных) могут выполняться методом do манипулятора базы данных. При этом возвращается логическая истина или ложь. Для команд SQL, возвращающих записи данных (например, SELECT), необходимо сначала вызвать метод pr
После завершения работы с базой не забудьте отключиться от нее методом disconnect. Если манипулягор базы данных выходит из области действия без предварительного вызова disconnect, модуль DBI выдает предупреждение. Эта мера предосторожности предназначе disconnect(OBI::db-HA8H(Ox9df84)) invalidates 1 active cursor(s) at -e line 1, Модуль DBI содержит 'FAQ(perldocDBI::FAQ) и стандартную документацию (j/ei'ldoc DBF). Также существует документация для драйверов конкретных СУБД (например, perldoc. DBD-.-.inysq!'). Прикладной интерфейс DBI не ограничивается простейшим подмножеством, рас Программа ил примера 14.7 создае! и заполняет таблицу пользователей в MySQL, после чего выполняет в ней поиск. Она использует атрибут RaiseError к потому обходится без проверки возвращаемого значения для каждого метода-Пример 14.7. dbusers

> Смотри также -------------------------------
Документация по DBI и модулям DBD с CPAN, http://www.hef7netica.com/ technologia/perl/DBI/index.html и http://www.perl/com/CPAN/modules/by-category/ О 7 _Database interfaces/.

14.11. Программа: ggh - поиск в глобальном журнале Netscape

Следующая программа выводит содержимое файла Netscape history, db. При вызове ей может передаваться полный URL или (один) шаблон. Если программа вызывается без аргументов, она выводит все содержимое журнала. Если не задан параметр -database, используется
В каждой выводимой строке указывается URL и время работы. Время преобразуется в формат localtime параметром -localtime (по умолчанию) или в представление gmtime параметром -gmtime или остается в первоначальном формате (параметр -epoch), что может приг
Шаблон задается единственным аргументом, не содержащим : //. Чтобы вывести данные по одному или нескольким URL, передайте их в качестве аргументов:
v% ggh http://www.perl.com/index.html
Вывод сведений о адресах, которые вы помните лишь приблизительно (шаблоном считается единственный аргумент, не содержащий : //):.
% ggh perl Вывод всех адресатов электронной почты:
% ggh mailto:

Для вывода всех посещенных сайтов со списками FAQ используется шаблон Perl с внутренним модификатором /I:
% ggh -regexp '(?i)\bfaq\b'

Если вы не хотите, чтобы внутренняя дата была преобразована в формат local time, используйте параметр -epoch:
% ggh -epoch http://www.perl.com/perl/ Если вы предпочитаете формат gmtime, используйте параметр -gmtime:
% ggh -gmtime http://www.perl.com/perl/

Чтобы просмотреть весь файл, не задавайте значения аргументов (вероятно, данные следует перенаправить в утилиту постраничного вывода):
% ggh | less Чтобы отсортировать выходные данные по дате, укажите флаг -epoch:
% ggh -epoch | sort -rn | less

Для сортировки по времени в формате местного часового пояса используется более сложная командная строка:
% ggh -epoch | sort -rn | perl -ре 's/\d+/localtime $&/e' | less

Сопроводительная документация Netscape утверждает, что в журнале используется формат NDBM. Это не соответствует действительности: на самом деле использован формат Berkeley DB, поэтому вместо NDBM_File (входит в стандартную поставку всех систем, на кот Пример 14.8. ggh
#!/usr/bin/perl -w
# ggh - поиск данных в журнале netscape
$USAGE = "EO_COMPLAINT;
usage: $0 [-database dbfilename] [-help]
[-epochtime | -localtime | -gmtime]
[ [-regexp] pattern] | href ... ] EO_COMPLAINT
use Getopt::Long;
($opt_database, $opt_epochtime, $opt_localtime, $opt_gmtime,
$opt_regexp, $opt_help, $pattern,
) = (0) x 7;
usage() unless GetOptions qw{ database=s regexp=s epochtime localtime gmtime help };
if ($opt_help) { print $USAGE; exit; }
usage("only one of localtime, gmtime, and epochtime allowed") if $opt_localtime +
$opt_gmtime + $opt_epochtime > 1;
if ( $opt_regexp ) {
$pattern = $opt_regexp;
} elsif (@ARGV && $ARGV[0] Г m(://)) {
$pattern = shift;
}
uoage("can't mix URLs and enpiiciL раИйгпа1;
if $pattern && @ARGV;
if ($pattern && ! eval {'"="' /$pattern/; 1 } ) {
$@ =~ s/ at \w+ line \d+\.//;
die "$0: bad pattern $@>";
}
require DB_File; DB_File->import();
# Отложить загрузку до выполнения
$1=1; # Для перенаправления данных
$dotdir = $ENV{HOME} || $ENV{LOGNAME};
$HISTORY = $opt_database || "$dotdir/.netscape/history.db";
die "no netscape history dbase in $HISTORY: $!" unless -e $HISTORY;
die "can't dbmopen $HISTORY: $!" unless dbmopen %hist_db, $HISTORY, 0666;
# Следующая строка - хак, поскольку программисты С,
# которые работали над этим, путали strlen и strlen+1.
# Так мне сказал jwz :-)
$add_nulls = (ord(substr(each %hist_db, -1)) == 0);
# XXX: Сейчас следовало бы сбросить скалярные ключи, но
# не хочется тратить время на полный перебор, И необходимый для связанных хэшей,
# Лучше закрыть и открыть заново?
$nulled_href = "";
$byte_order = "V"; # На PC не понимают "N" (сетевой порядок)
if (@>ARGV) {
foreach $href (@ARGV) {
$nulled_href = $href . ($add_nulls && "\0");
unless ($binary_time = $hist_db{$nulled_href}) { warn "$0: No history entry for HREF
$href\n";
next;
} $epoch_secs = unpack($byte_order, $binary_time);
$stardate = $opt_epochtime ? $epoch_secs
: $opt_gmtime ? gmtime $epoch_secs : localtime $epoch_secs;
print "$stardate $href\n";
}
} else {
while ( ($href, $binary_time) = each %hist_db ) {
chop $href if $add_nulls;
# gnat reports some binary times are missing
$binary_time = pack($byte_order, 0) unless $binary_time;
$epoch_secs = unpack($byte_order, $binary_time):
$stardate = $opt_epochtime ? $epoch_secs
: $opt_gmtime ? gmtime $epoch_secs : localtime $epoch_secs;
print "$stardate $href\n" unless $pattern && $href !~ /$pattern/o;
}
}
sub usage {
print STDERR "@_\n" if (o)_
die $USAGE:
}


> Смотри также Рецепт 6.17.
© copyright 2000 Soft group

Используются технологии uCoz