Использование языка Perl
Содержание
6.1Основные особенности Perl
6.1.1Введение
6.2Взаимодействие с СУБД
6.2.1Взаимодействие с Oracle
6.2.1.1Основные функции доступа
6.2.1.2Дополнительные функции
6.2.1.3Переменные
6.2.1.4Переменные для подстановки
6.3Написание модулей CGI
6.4Обработка файлов формата DBF
6.1 Основные особенности Perl
6.1.1 Введение
Perl - интерпретируемый язык, приспособленный для обработки произвольных текстовых файлов, извлечения из них необходимой информации и выдачи сообщений.
Perl также удобен для написания различных системных программ. Этот язык прост в использовании, эффективен, но про него трудно сказать, что он элегантен и
компактен. Perl сочитает в себе лучшие черты C, shell, sed и awk,
поэтому для тех, кто знаком с ними, изучение Perl-а не представит особого труда. Cинтаксис выражений Perl-а близок к синтаксису C. В
отличие от большинства утилит ОС UNIX Perl не ставит ограничений на объем обрабатываемых данных и если хватает ресурсов, то весь файл обрабатывается как
одна строка. Рекурсия может быть произвольной глубины. Хотя Perl приспособлен для обработки текстовых файлов, он может обрабатывать так же двоичные данные и
создавать .dbm файлы, подобные ассоциативным массивам. Perl позволяет использовать регулярные выражения, создавать объекты, вставлять в программу на
С или C++ куски кода на Perl-е, а также позволяет осуществлять доступ к базам данных, в том числе Oracle.
Этот язык часто используется для написания CGI-модулей, которые, в свою очередь, могут обращаться к базам данных. Таким образом может
осуществляться доступ к базам данных через WWW.
Perl позволяет осуществлять доступ к различным СУБД. Здесь будет освещен вопрос доступа к СУБД Oracle.
6.2.1 Взаимодействие с Oracle 6.2.1.1 Основные функции доступаМы приведем здесь пример программы, которая создает таблицу, помещает в нее некоторые данные и потом производит выборку строк из этой таблицы.
#!/usr/local/bin/perluse 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 EMPwhere 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
Для того, чтобы получить доступ к информации, хранимой в Oracle
необходимо сначала войти в систему. Это осуществляется вызовом функции &ora_login().
Эта функция имеет три параметра: системный идентификатор базы данных, имя пользователя в базе и пароль пользователя. Возвращается идентификатор
регистрации в системе (Oracle Login Data Area). Несколько доступов могут осуществляться
одновременно. Эта функция эквивалентна функции OCI(Oracle Call Interface) olon
или orlon.
&ora_open
Для определения SQL-запроса в базу данных программа должна вызывать функцию &ora_open. Эта функция имеет как минимум два параметра: идентификатор регистрации и SQL выражение. Необязательный третий параметр описывает размер буфера строк для SELECT оператора. Возвращается курсор Oracle. Если третий параметр опущен, то используется стандартный размер буфера.
$csr = &ora_open($lda,'select ename,sal from emp order by ename',10);Эта функция эквивалентна функции OCI oopen или oparse.
&ora_bind
Если 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
Эта функция используется с оператором SQL SELECT для извлечения информации из базы данных и имеет только один обязательный параметр - идентификатор
курсора, полученный в результате вызова функции &ora_open. В скалярном контексте она возвращает число выбранных строк, в списковом - массив
выбранных строк. Второй необязательный параметр содержит информацию о том, можно ли обрезать данные типов LONG и LONG RAW или выдавать
сообщение об ошибке. Если параметр опущен, то информация берется из переменной $ora_trunc.
Если произошло обрезание данных, то переменная $ora_errno принимает значение 1406.
Эта функция эквивалентна функции OCI ofetch.
&ora_close
Если открытый курсор не будет больше использоваться, то его нужно закрыть
вызовом функции &ora_close. Это эквивалентно функции OCI oclose.
&ora_do
Не все 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. Она эквивалентна функции OCI ologoff.
6.2.1.2 Дополнительные функцииДополнительные возможности предоставляются функциями
&ora_titles()
&ora_length()
&ora_types()
&ora_autocommit()
&ora_commit()
&ora_rollback()
&ora_version()
&ora_titles
Программа может определить название полей, содержимое которых будет
извлечено запросом, вызовом функции &ora_title. Эта функция имеет один параметр - курсор. Заголовки обрезаются до длины поля.
&ora_length
Программа может определить длину каждого из полей, возвращенных запросом, с
помощью вызова функции &ora_length. Она имеет только один параметр - курсор и возвращает массив целых чисел.
&ora_types
Программа может определить тип каждого из полей, возвращенных запросом, с
помощью вызова функции &ora_types. Она имеет один параметр - курсор и возвращает массив целых чисел. Эти типы
определяются в документации по OCI и в файле oraperl.ph для Oracle v6.
&ora_autocommit
Режим автоматического завершения транзакций можно установить или отменить
вызовом функции &ora_autocommit. Эта функция имеет два параметра: идентификатор регистрации и булевскую
переменную, которая указывает действие, которое нужно выполнить. Если значение переменной ненулевое, то режим включается, если нулевое, то отключается. По
умолчанию режим не включен. Режим включается на продолжительность пребывания в системе. Если есть необходимость включать его только для одного оператора, то
лучше делать несколько регистраций и использовать для каждого оператора отдельный идентификатор регистрации.
&ora_commit, &ora_rollback
Изменения в базе данных могут быть сохранены или отменены вызовом этих
функций. Они имеют один параметр - идентификатор регистрации в системе. Транзакции, результат которых уже был сохранен не могут быть отменены &ora_rollback.
Эти функции также действуют на все время пребывания в системе, а не на отдельные операторы.
&ora_version
Эта функция печатает версию и информацию об авторских правах, касающуюся Oraperl. Она не возвращает ничего.
6.2.1.3 ПеременныеВ модуле 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 выполняет подстановку именно в таком порядке.
6.3 Написание модулей CGIЯзык Perl очень широко используется при написании исполняемых модулей CGI (Common Gateway Interface) для Web. Это обусловлено прежде всего тем, что Perl предоставляет разработчикам простые и удобные средства обработки текста и взаимодействия с базами данных. Наша цель - лишь дать пример использования Perl для написания CGI-модуля. Рассмотрим простую подпрограмму разбора входного потока CGI-программы (при передаче параметров используется метод POST ).
#!/usr/local/bin/perlsub Print {$len = 100;$buf = "";read(STDIN, $buf,$len);# считываем из стандартного потока ввода# в переменную $buf количество символов# $len@ar = split(/[&=]/,$buf);# разбиваем строку в массив строк,# разделителями служат & и =.$output = "Content-type: text/htmlnn# посылает тип MIME передаваемого документаResultHi there";$i = 0;while ($i open_dbf($dbf_name,$idx_name);
Мы ассоциировали DBF-файл и необязательный индексный файл с объектом. Чтобы определить тип (database type) можно сделать следующее:
print $database->dbf_type;Вернется строка, которая, если Xbase файл открыт, будет содержать значение DBF3, DBF4 или FOX. Чтобы узнать дату последнего обновления делается следующее:
print $database->last_update;Возвращает строку с датой.
Чтобы узнать номер последней записи можно сделать следующее:
Вернется номер последней записи в файле с базой данных.
Информацию о статусе базы данных можно посмотреть следующим образом:
В стандартный выходной поток будет напечатана информация о статусе и
структуре базы данных. Этот метод работает аналогично команде display status.
Посмотреть информацию о статусе индексного файла можно используя метод idx_stat:
Печатает в стандартный выходной поток (STDOUT) информацию о статусе
открытого IDX-файла.
Для того чтобы перейти на начало файла есть метод go_top:
Передвигает курсор чтения на физическое начало файла,если индексы не
существуют и на первую запись, соответствующую порядку, который задается индексом, в противоположном случае.
Для того чтобы перейти на конец файла есть метод go_bottom:
Передвигает курсор чтения на физический конец файла,если индексы не
существуют и на последнюю запись, соответствующую порядку, который задается индексом, в противоположном случае.
Чтобы перейти на следующую запись есть метод go_next:
Эквивалентно команде skip 1, которая передвигает курсор на
следующую запись.
Чтобы перейти на предыдущую запись есть метод go_prev:
Эквивалентно команде skip -1, которая передвигает курсор на
предыдущую запись.
Есть возможность осуществить поиск по заданному ключу:
Эта команда устанавливает курсор на первую запись, соответствующую данному
ключу. Но в данном случае база данных должна быть открыта с соответствующим индексом, в противоположном случае будет выдано сообщение об ошибке и исполнение
прекратиться. Возвращается значение, содержащее информацию о том, был ключ найден или нет.
Чтобы узнать номер записи, на которой стоит курсор можно использовать следующую команду:
Метод 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.
Чтобы прочитать значения полей записи в массив можно поступить так:
В массиве они будут располагаться в такой же последовательности, как и в
базе данных.
Для закрытия базы данных используется метод close_dbf.
Закрывает файл с базой данных, индексами и комментариями. В завершение приведем небольшой пример программы, которая распечатывает статус базы данных и индексного файла, а также дату последнего обновления и количество записей в базе данных.
#!/usr/bin/perluse 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;#печатаем номер последней записи