|
Основное первоначальное предназначение языка программирования Perl, то, ради чего, собственно, он и был разработан, — облегчить системному администратору UNIX обработку большого числа текстовых файлов при настройке операционной системы и автоматизировать создание отчетов по использованию ее ресурсов на основе специальных системных текстовых файлов. Отсюда и его полное название «Practical Extraction and Report language» («Практический язык извлечений и отчетов»).
Язык Perl родился в среде операционной системы UNIX как реакция одного талантливого программиста на ограниченные возможности существовавших тогда в этой операционной среде стандартных средств системного администрирования.
Perl был разработан Ларри Уоллом (Larry Wall) в 1986 году. Ларри Уолл являлся в то время системным администратором одного проекта UNIX, связанного с созданием многоуровневой безопасной сети, которая объединяла несколько компьютеров, разнесенных на большие расстояния.
Perl - интерпретируемый язык, приспособленный для обработки произвольных текстовых
файлов, извлечения из них необходимой информации и выдачи сообщений. Perl также удобен для
написания различных системных программ. Этот язык прост в использовании, эффективен, но про
него трудно сказать, что он элегантен и компактен. Perl сочитает в себе лучшие черты C, shell, sed
и awk, поэтому для тех, кто знаком с ними, изучение Perl-а не
представит особого труда. Cинтаксис выражений Perl-а близок к синтаксису C.
В отличие от большинства утилит ОС UNIX
Perl не ставит ограничений на объем обрабатываемых данных и если
хватает ресурсов, то весь файл обрабатывается как одна строка.
Рекурсия может быть произвольной глубины. Хотя Perl приспособлен для
обработки текстовых файлов, он может обрабатывать так же двоичные
данные и создавать .dbm файлы, подобные ассоциативным массивам.
Perl позволяет использовать регулярные выражения, создавать
объекты, вставлять в программу на С или C++ куски кода на Perl-е, а также
позволяет осуществлять доступ к базам данных, в том числе Oracle.
Этот язык часто используется для написания CGI-модулей, которые,
в свою очередь, могут обращаться к базам данных. Таким образом может
осуществляться доступ к базам данных через WWW.
Perl позволяет осуществлять доступ к различным СУБД. Здесь будет освещен вопрос доступа к СУБД Oracle.
Мы приведем здесь пример программы, которая создает таблицу, помещает в нее некоторые данные и потом производит выборку строк из этой таблицы.
#!/usr/local/bin/perl use Oraperl; # подключаем модуль Oraperl $system_id = 'T:bdhost.com:Base'; $lda = &ora_login($system_id,'scott','tiger'); # вход в систему $st = 'create table EMP (name varchar2(100), organization varchar2(100))'; $csr = &ora_open($lda,$st) || die $ora_errstr; &ora_close($csr); # создание таблицы в базе данных $st = 'insert into EMP values (\'John Smit\', \'NATO\')'; $csr = &ora_open($lda, $st); &ora_close($csr); # помещение строки в таблицу
В результате в базе создалась
таблица из двух столбцов с одной
записью:
Name | Organization |
John Smit | NATO |
$st = 'select name from EMP where organization = \'NATO\''; $csr = &ora_open($lda,$st); # выбираем из таблицы значения столбца name, # которым сответствует значение столбца organization # равное 'NATO' @result = &ora_fetch($csr); # помещаем эти значения в массив @result &ora_close($csr); print @result; &ora_logoff($lda); # выход из системы
Для взаимодействия с Oracle
в
Perl есть специальный модуль Oraperl.pm
.
Основными функциями для доступа к
базе данных являются:
&ora_login
$lda = &ora_login($system_id,$username,$password)
Для того, чтобы получить доступ к
информации, хранимой в Oracle
необходимо сначала войти в систему.
Это осуществляется вызовом функции
&ora_login()
. Эта функция имеет
три параметра: системный
идентификатор базы данных, имя
пользователя в базе и пароль
пользователя. Возвращается
идентификатор регистрации в
системе (Oracle Login Data Area
).
Несколько доступов могут
осуществляться одновременно. Эта
функция эквивалентна функции OCI(Oracle
Call Interface) olon
или orlon
.
&ora_open
$csr = &ora_open($lda, $statement [,$cache])
Для определения SQL-запроса в базу
данных программа должна вызывать
функцию &ora_open
. Эта функция
имеет как минимум два параметра:
идентификатор регистрации и SQL
выражение. Необязательный третий
параметр описывает размер буфера
строк для SELECT оператора.
Возвращается курсор Oracle
.
Если третий параметр опущен, то
используется стандартный размер
буфера.
$csr = &ora_open($lda,'select ename, sal from emp order by ename',10);
Эта функция эквивалентна функции
OCI oopen
или oparse
.
&ora_bind
&ora_bind($csr, $var, ...)
Если SQL выражение содержит
обращение к переменным языка Perl,
то необходимо подставить вместо
имен значения переменных. Для этого
используется функция &ora_bind
.
$csr = &ora_open($lda, 'insert into emp values (:1,:2)'); &ora_bind($csr,$ename,$sal);
- подставляет в SQL выражение
вместо :1 и :2 значения
переменных $ename
и $sal
.
&ora_fetch
$nfields = &ora_fetch($csr[, trunc]); @array = &ora_fetch($csr);
Эта функция используется с
оператором SQL SELECT для извлечения
информации из базы данных и имеет
только один обязательный параметр -
идентификатор курсора, полученный
в результате вызова функции &ora_open
.
В скалярном контексте она
возвращает число выбранных строк, в
списковом - массив выбранных строк.
Второй необязательный параметр
содержит информацию о том, можно ли
обрезать данные типов LONG
и LONG
RAW
или выдавать сообщение об
ошибке. Если параметр опущен, то
информация берется из переменной $ora_trunc
.
Если произошло обрезание данных, то
переменная $ora_errno
принимает
значение 1406. Эта функция
эквивалентна функции OCI ofetch
.
&ora_close
&ora_close($csr)
Если открытый курсор не будет
больше использоваться, то его нужно
закрыть вызовом функции &ora_close
.
Это эквивалентно функции OCI oclose
.
&ora_do
&ora_do($lda,$statement)
Не все SQL-выражения возвращают
данные или содержат переменные для
подстановки. В таких случаях
функция &ora_do
выступает в
качестве альтернативы &ora_open
и &ora_close
. Первым параметром
является идентификатор
регистрации, вторым -- SQL выражение.
&ora_do($lda,'drop table employee');
это эквивалентно:
&ora_close(&ora_open($lda, 'drop table employee'));
&ora_logoff
&ora_logoff($lda)
Для выхода из системы
используется функция &ora_logoff
.
Она эквивалентна функции OCI ologoff
.
Дополнительные возможности
предоставляются функциями
&ora_titles()
&ora_length()
&ora_types()
&ora_autocommit()
&ora_commit()
&ora_rollback()
&ora_version()
&ora_titles
@titles = &ora_titles($csr)
Программа может определить
название полей, содержимое которых
будет извлечено запросом, вызовом
функции &ora_title
. Эта функция
имеет один параметр - курсор.
Заголовки обрезаются до длины поля.
&ora_length
@length = &ora_length($csr)
Программа может определить длину
каждого из полей, возвращенных
запросом, с помощью вызова функции &ora_length
.
Она имеет только один параметр -
курсор и возвращает массив целых
чисел.
&ora_types
@types = &ora_types($csr)
Программа может определить тип
каждого из полей, возвращенных
запросом, с помощью вызова функции &ora_types
.
Она имеет один параметр - курсор и
возвращает массив целых чисел. Эти
типы определяются в документации
по OCI и в файле oraperl.ph
для Oracle
v6
.
&ora_autocommit
&ora_autocommit($lda,$on_or_off)
Режим автоматического завершения
транзакций можно установить или
отменить вызовом функции &ora_autocommit
.
Эта функция имеет два параметра:
идентификатор регистрации и
булевскую переменную, которая
указывает действие, которое нужно
выполнить. Если значение
переменной ненулевое, то режим
включается, если нулевое, то
отключается. По умолчанию режим не
включен. Режим включается на
продолжительность пребывания в
системе. Если есть необходимость
включать его только для одного
оператора, то лучше делать
несколько регистраций и
использовать для каждого оператора
отдельный идентификатор
регистрации.
&ora_commit, &ora_rollback
&ora_commit($lda) &ora_rollback($lda)
Изменения в базе данных могут
быть сохранены или отменены
вызовом этих функций. Они имеют
один параметр - идентификатор
регистрации в системе. Транзакции,
результат которых уже был сохранен
не могут быть отменены &ora_rollback
.
Эти функции также действуют на все
время пребывания в системе, а не на
отдельные операторы.
&ora_version
&ora_version()
Эта функция печатает версию и
информацию об авторских правах,
касающуюся Oraperl
. Она не
возвращает ничего.
В модуле Oraperl.pm есть шесть
специальных переменных:
$ora_cache
$ora_long
$ora_trunc
$ora_errno
$ora_errstr
$ora_verno
Эти переменные используются для
определения поведения Oraperl
в
определенных условиях.
$ora_cache Эта переменная
определяет размер буфера для
функции &ora_open()
и
SELECT-выражения, если точный размер
буфера не указан. Как правило
устанавливается размер буфера
равный пяти. Присваивание этой
переменной значения, равного нулю,
устанавливает значение этой
переменной равным первоначальному
значению. Присваивание
отрицательной величины приводит к
ошибке.
$ora_long Обычно Oraperl
спрашивает базу данных о длине
каждого поля и соответствующим
образом распределяет буферное
пространство. Это невозможно для
полей типа LONG
и LONGRAW
.
Распределение пространства в
предположении максимально
возможной длины (65535 bytes
)
привело бы к излишним тратам
памяти. Поэтому когда &ora_open()
определяет, что поле имеет тип LONG
,
память распределяется согласно
значению переменной $ora_long
.
При инициализации она принимает
значение 80 (для совместимости с
продуктами Oracle
), но в
программе ее можно устанавливать
произвольным образом.
$ora_trunc Так как Oraperl
не может точно определять длину
значений типа LONG
, возникают
ситуации, когда значение $ora_long
недостаточно для хранения
полученных данных. В таком случае,
если у &ora_fetch
есть
необязательный второй параметр,
происходит обрезание данных. Если
второй параметр опущен, то вместо
него используется значение $ora_trunc
.
$ora_errno Содержит код ошибки
произошедшей при последнем вызове
какой-либо функции. Есть два
интересных случая, касающихся &ora_fetch()
.
В первом случае, если произошло
обрезание данных типа LONG
или
LONGRAW
и обрезание было
разрешено, тогда выполнение этой
функции полностью успешно, но $ora_errno
принимает значение 1406, для
индикации того, что произошло
обрезание. Во втором случае, если &ora_fetch()
возвратила false
, то $ora_errno
принимает значение 0 в случае конца
данных или код ошибки, если
действительно произошла ошибка.
$ora_errstr Содержит сообщение
об ошибке, соответствующее
значению $ora_errno
.
$ora_verno Содержит версию Oraperl
в формате v.ppp, где v - основной номер
версии, а ppp - patchlevel.
Oraperl
позволяет SQL выражению
содержать обращение к переменным
языка Perl. Они состоят из
двоеточия и следующего за ним
номера. Например:
$csr = &ora_open($lda,"insert into tel values(:1,:2)");
Эти два имени :1 и :2
называются переменными для
подстановки. Функция &ora_bind()
используется для привязывания
переменных к их значениям.
&ora_bind($csr, "Annette","3-222-2-22-22-22"); &ora_bind($csr,$name,$telephone);
Номера переменных должны
следовать в порядке возрастания
начиная с 1, так как &ora_bind
выполняет подстановку именно в
таком порядке.
Язык Perl очень широко используется
при написании исполняемых модулей
CGI (Common Gateway Interface) для Web. Это
обусловлено прежде всего тем, что
Perl предоставляет разработчикам
простые и удобные средства
обработки текста и взаимодействия
с базами данных. Наша цель - лишь
дать пример использования Perl для
написания CGI-модуля. Рассмотрим
простую подпрограмму разбора
входного потока CGI-программы (при
передаче параметров используется
метод POST
).
#!/usr/local/bin/perl sub Print { $len = 100; $buf = ""; read(STDIN, $buf,$len); # считываем из стандартного потока ввода # в переменную $buf количество символов # $len @ar = split(/[&=]/,$buf); # разбиваем строку в массив строк, # разделителями служат & и =. $output = "Content-type: text/html\n\n # посылает тип MIME передаваемого документа <HTML><HEAD><TITLE>Result</TITLE></HEAD> <BODY BGCOLOR=\"#FFAAAA\"> <H1>Hi there</H1><HR><BR>"; $i = 0; while ($i <= $#ar) { $ar[$i] =~ s/\+/ /g; # заменяем в элементах массива + на пробел $output .= "$ar[$i]\n"; # конкатенация переменной $output с # элементом массива $i++; } $output .="<HR></BODY></HTML>"; # завершаем HTML страницу print $output; } eval &Print; # выполняем подпрограмму осуществляющую # считывание, обработку и вывод информации
В данном примере был
проиллюстрирован случай
считывания параметров из входного
потока. Если параметры передаются
CGI-модулю в командной строке, то они
помещаются в служебный массив @ARGV
.
Например, если параметры пишуться в
URL:
http://www.host.ru/cgi-bin/name.cgi?123+resource+time+12
.
Как видно из примера, написать
CGI-модуль на Perl совсем не
сложно. Существуют также различные
модули для облегчения написания CGI.
Документацию по ним и сами модули
доступны на сервере www.perl.com
Для взаимодействия с файлами
этого формата существует
специальный модуль - Xbase.pm
На
текущий момент поддерживается
только возможность чтения таких
файлов. Этот модуль подключается
стандартным образом: use Xbase;
Новый Xbase
объект создается
следующим образом:
$database = new Xbase;
Будет создан объект $database
,
который в дальнейшем будет
использоваться для взаимодействия
со всевозможными методами, которые
поддерживает модуль. Доступ к базе
данных осуществляется следующим
образом:
$database->open_dbf($dbf_name,$idx_name);
Мы ассоциировали DBF-файл и необязательный индексный файл с объектом. Чтобы определить тип (database type) можно сделать следующее:
print $database->dbf_type;
Вернется строка, которая, если Xbase
файл открыт, будет содержать
значение DBF3, DBF4 или FOX. Чтобы узнать
дату последнего обновления
делается следующее:
print $database->last_update;
Возвращает строку с датой.
Чтобы узнать номер последней
записи можно сделать следующее:
$end=$database->lastrec;
Вернется номер последней записи в
файле с базой данных.
Информацию о статусе базы данных
можно посмотреть следующим
образом:
$database->dbf_stat;
В стандартный выходной поток
будет напечатана информация о
статусе и структуре базы данных.
Этот метод работает аналогично
команде display status
.
Посмотреть информацию о статусе
индексного файла можно используя
метод idx_stat
:
$database->idx_stat;
Печатает в стандартный выходной
поток (STDOUT) информацию о статусе
открытого IDX-файла.
Для того чтобы перейти на начало
файла есть метод go_top
:
$database->go_top;
Передвигает курсор чтения на
физическое начало файла,если
индексы не существуют и на первую
запись, соответствующую порядку,
который задается индексом, в
противоположном случае.
Для того чтобы перейти на конец
файла есть метод go_bottom
:
$database->go_bottom;
Передвигает курсор чтения на
физический конец файла,если
индексы не существуют и на
последнюю запись, соответствующую
порядку, который задается индексом,
в противоположном случае.
Чтобы перейти на следующую запись
есть метод go_next
:
$database->go_next;
Эквивалентно команде skip 1
,
которая передвигает курсор на
следующую запись.
Чтобы перейти на предыдущую запись
есть метод go_prev
:
$database->go_prev;
Эквивалентно команде skip -1
,
которая передвигает курсор на
предыдущую запись.
Есть возможность осуществить поиск
по заданному ключу:
$stat=$database->seek($keyvalue);
Эта команда устанавливает курсор
на первую запись, соответствующую
данному ключу. Но в данном случае
база данных должна быть открыта с
соответствующим индексом, в
противоположном случае будет
выдано сообщение об ошибке и
исполнение прекратиться.
Возвращается значение, содержащее
информацию о том, был ключ найден
или нет.
Чтобы узнать номер записи, на
которой стоит курсор можно
использовать следующую команду:
$current_rec=$database->recno;
Метод bof
возвращает
значение true
, если курсор
находится в самом начале файла.
if ($database->bof) { print " At the very top of the file \n"; }
Аналогично действует метод eof
:
if ($database->eof) { print " At the very end of the file \n"; }
Чтобы прочитать содержимое какого-либо поля записи можно поступить так:
print $database->get_field("NAME");
Возвращает строку с содержимым
поля. Если данная запись помечена
для удаления, то использует
псевдоимя поля _DELETED
.
Чтобы прочитать значения полей
записи в массив можно поступить так:
@fields = $database->get_record;
В массиве они будут располагаться в такой же последовательности, как
и в базе данных.
Для закрытия базы данных используется метод close_dbf
.
$database->close_dbf;
Закрывает файл с базой данных, индексами и комментариями. В завершение приведем небольшой пример программы, которая распечатывает статус базы данных и индексного файла, а также дату последнего обновления и количество записей в базе данных.
#!/usr/bin/perl use Xbase; # подключение модуля $database = new Xbase; # создание объекта $d = "/home/smit/employee.dbf"; # имя файла с базой $i = "/home/smit/employee.cdx"; # имя индексного файла $database->open_dbf($d,$i); # открываем базу данных $database->dbf_stat; # печатаем статус и структуру # базы данных $database->idx_stat; # печатаем статус и структуру # индексов @fields = $database->get_record; print @fields,"\n"; # печатаем содержимое текущей записи print $database->last_update, "\n"; # печатаем дату последнего обновления $end = $database->lastrec; print $end; #печатаем номер последней записи
Полная спецификация языка Perl приводиться в Приложении 2.