PACKAGE phone IS
-- Главное меню
PROCEDURE MENU;
-- Список подразделений НГУ, если не определен параметр ID
-- Список абонентов подразделения НГУ, которое определяет ID
PROCEDURE SUBDIVISIONS(ID VARCHAR2 DEFAULT NULL);
-- Перечень букв алфавита на которые начинаются фамилии абонентов
PROCEDURE NAME;
-- Список абонентов, первая буква фамилии которых равна LETTER
PROCEDURE NAME(LETTER VARCHAR2);
-- Вся информация имеющаяся в БД об абоненте
PROCEDURE PERSON(ID VARCHAR2);
-- Выводит форму для ввода условия поиска
PROCEDURE QUERY;
-- Список абонентов, удовлетворяющий условию поиска по ФИО
PROCEDURE QUERY_NAME(LETTERS VARCHAR2 DEFAULT NULL);
END;
PACKAGE BODY phone IS
pkg VARCHAR2(100) := 'nsu.phone.'; --имя этого пакета
-- Заголовок HTML - документа
PROCEDURE HEADER(TT VARCHAR2) IS
BEGIN
htp.p('<HTML>');
htp.p('<HEAD>');
htp.p('<TITLE>'||TT||'</TITLE>');
htp.p('</HEAD>');
htp.p('<BODY BGCOLOR="#FFFFFF">');
htp.p('<TABLE WIDTH="100%" BGCOLOR="CCCCCC"><TR><TD ALIGN="CENTER"><B>Телефонный справочник НГУ</B></TABLE>');
htp.p('<P><P><P>');
END;
-- Конец HTML - документа
PROCEDURE FOOTER IS
BEGIN
htp.p('<P><P><P>');
htp.p('<CENTER>');
htp.p('<HR>');
htp.p('<FONT SIZE="-1">');
htp.p('Информация предоставлена Отделом Средств Связи НГУ.<BR>тел.39-71-00');
htp.p('<HR>');
htp.p('<EM>© <A HREF="mailto:zev@nsu.ru">Evgeny Zybarev</A>, 1996</EM>');
htp.p('</FONT>');
htp.p('</CENTER>');
htp.p('</BODY>');
htp.p('</HTML>');
END;
-- Вывод сообщения об ошибке
PROCEDURE sqlerror IS
BEGIN
HEADER('Ошибка!');
htp.p('<B>'||sqlerrm||'</B>');
FOOTER;
END;
-- Выводит список абонентов
-- Если PRM2 определено, то выбираются абоненты, работающие в подразделении
-- "1-го" уровня PRM и подразделении "2-го" уровня PRM2
-- Если PRM2 не определено, то выбираются абоненты,
-- чьи ФИО соответствую шаблону PRM
PROCEDURE PHONE_LIST(PRM VARCHAR2 DEFAULT '%', PRM2 VARCHAR2 DEFAULT NULL) IS
Cursor frm1 is
select Должность f1, ФИО f2, "Сл# телефон" f3, Место f4, ROWID
from TEL_SPIS
where upper(ПОДР) like upper(PRM) and
upper(ПОДРАЗДЕЛЕНИЕ) like upper(PRM2)
order by Должность;
Cursor frm2 is
select ФИО f2, "Сл# телефон" f3, Место f4, "Дом# телефон" f5, ROWID
from TEL_SPIS
where upper(ФИО) like upper(PRM)||'%'
order by ФИО;
ff VARCHAR2(100) := 'dummy';
FRM Number(1) := 1;
BEGIN
If PRM2 is not NULL Then FRM := 1; Else FRM := 2; End If;
htp.p('<TABLE WIDTH="100%" COLS="4" BORDERCOLOR="#CCCCCC">');
htp.p('<TR BGCOLOR="#CCCCCC">');
If FRM=1 Then htp.p('<TH>Должность или<BR>подразделение'); End If;
htp.p('<TH>Фамилия, имя, отчество');
htp.p('<TH>Телефон');
If FRM=2 Then htp.p('<TH>Домашний<BR>телефон'); End If;
htp.p('<TH>Номер комнаты<BR>и корпус');
If FRM=1 Then
For rec in frm1 Loop
htp.p('<TR ALIGN="LEFT">');
If ff!=rec.f1||rec.f2 Then
ff:=rec.f1||rec.f2;
htp.p('<TD>'||rec.f1);
htp.p('<TD><A HREF="'||pkg||'person?ID='||rec.ROWID||'">'||rec.f2||'</A>');
Else
htp.p('<TD><TD>');
End If;
htp.p('<TD ALIGN="CENTER">'||rec.f3);
htp.p('<TD ALIGN="CENTER">'||rec.f4);
End Loop;
ElsIf FRM=2 Then
For rec in frm2 Loop
htp.p('<TR ALIGN="LEFT">');
htp.p('<TD>');
If ff!=rec.f2 Then
ff:=rec.f2;
htp.p('<A HREF="'||pkg||'person?ID='||rec.ROWID||'">'||rec.f2||'</A>');
End If;
htp.p('<TD ALIGN="CENTER">'||rec.f3);
htp.p('<TD ALIGN="CENTER">'||rec.f5);
htp.p('<TD ALIGN="CENTER">'||rec.f4);
End Loop;
End If;
htp.p('</TABLE>');
END;
-- Главное меню
PROCEDURE MENU IS
BEGIN
HEADER('Телефонный справочник НГУ');
htp.p('<CENTER>');
htp.p('<TABLE BGCOLOR="#FFFFCC" WIDTH="50%" BORDER="1">');
htp.p('<TR ALIGN="CENTER">');
htp.p('<TD>');
htp.p('<A HREF="'||pkg||'subdivisions"><FONT SIZE="+2">Подразделения НГУ</FONT></A>');
htp.p('</TD>');
htp.p('</TR>');
htp.p('<TR ALIGN="CENTER">');
htp.p('<TD>');
htp.p('<A HREF="'||pkg||'name"><FONT SIZE="+2">Именной указатель</FONT></A>');
htp.p('</TD>');
htp.p('<TR ALIGN="CENTER">');
htp.p('<TD>');
htp.p('<A HREF="'||pkg||'query"><FONT SIZE="+2">Поиск по ФИО</FONT></A>');
htp.p('</TD>');
htp.p('</TR>');
htp.p('</TABLE>');
htp.p('</CENTER>');
FOOTER;
EXCEPTION WHEN OTHERS THEN sqlerror;
END;
-- Список подразделений НГУ, если не определен параметр ID
-- Список абонентов подразделения НГУ, которое определяет ID
PROCEDURE SUBDIVISIONS(ID VARCHAR2 DEFAULT NULL) IS
cursor sd is
select ПОДРАЗДЕЛЕНИЕ f1, max(ROWID) f2 from TEL_SPIS
group by ПОДРАЗДЕЛЕНИЕ order by 1;
BEGIN
HEADER('Телефонный справочник НГУ. Подразделения.');
If ID is NULL Then
htp.p('<CENTER><FONT SIZE="+1">Подразделения</FONT></CENTER>');
htp.p('<HR>');
htp.p('<UL>');
For rec in sd Loop
htp.p('<LI><A HREF="'||pkg||'subdivisions?ID='||rec.f2||'">'||rec.f1||'</A>');
End Loop;
htp.p('</UL>');
Else
Declare
pdr VarChar2(100);
Begin
For rec in (select ПОДРАЗДЕЛЕНИЕ f1 from TEL_SPIS where ROWID=ID) Loop
htp.p('<CENTER><FONT SIZE="+2"><B>'||rec.f1||'</B></FONT></CENTER>');
htp.p('<HR>');
pdr := rec.f1;
End Loop;
For rec in (select DISTINCT ПОДР f1 from TEL_SPIS
where ПОДРАЗДЕЛЕНИЕ=pdr and ПОДР=pdr order by 1)
Loop
PHONE_LIST(rec.f1,pdr);
End Loop;
For rec in (select DISTINCT ПОДР f1 from TEL_SPIS
where ПОДРАЗДЕЛЕНИЕ=pdr and ПОДР!=pdr order by 1)
Loop
htp.p('<HR>');
htp.p('<CENTER><FONT SIZE="+2">'||rec.f1||'</FONT></CENTER>');
htp.p('<HR>');
PHONE_LIST(rec.f1,pdr);
End Loop;
End;
End If;
FOOTER;
EXCEPTION WHEN OTHERS THEN sqlerror;
END;
-- Перечень букв алфавита на которые начинаются фамилии абонентов
PROCEDURE NAME IS
Cursor alf is select DISTINCT upper(substr(ФИО,1,1)) f1
from TEL_SPIS
where ФИО is not NULL
order by 1;
i Number := 0;
n Number := 10;
BEGIN
HEADER('Телефонный справочник НГУ. Именной указатель.');
htp.p('<CENTER>');
htp.p('<TABLE BORDER="1" CELLSPACING="3" CELLPADDING="3">');
htp.p('<CAPTION>');
htp.p('<HR WIDTH="300">');
htp.p('<FONT SIZE="+2">Именной указатель</FONT>');
htp.p('<HR WIDTH="300">');
htp.p('</CAPTION>');
htp.p('<TR BGCOLOR="#CCCCCC" ALIGN="CENTER">');
For rec in alf Loop
If i=n Then
htp.p('<TR BGCOLOR="#CCCCCC" ALIGN="CENTER">');
i:=0;
End If;
i := i+1;
htp.p('<TD>');
htp.p('<FONT SIZE="+2">');
htp.p('<A HREF="'||pkg||'name?LETTER='||to_char(ascii(rec.f1))||'">'||rec.f1||'</A>');
htp.p('</FONT>');
End Loop;
For j in i+1..n Loop
htp.p('<TD> ');
End Loop;
htp.p('</TABLE>');
htp.p('</CENTER>');
FOOTER;
EXCEPTION WHEN OTHERS THEN sqlerror;
END;
-- Список абонентов, первая буква фамилии которых равна LETTER
PROCEDURE NAME(LETTER VARCHAR2) IS
ff VARCHAR2(100):='dummy';
BEGIN
HEADER('Телефонный справочник НГУ. Именной указатель. '||LETTER);
htp.p('<CENTER>');
htp.p('<FONT SIZE="+1">Именной указатель</FONT>');
htp.p('<BR><FONT SIZE="+5">= '||chr(LETTER)||' =</FONT>');
htp.p('</CENTER>');
PHONE_LIST(chr(LETTER));
FOOTER;
EXCEPTION WHEN OTHERS THEN sqlerror;
END;
-- Вся информация имеющаяся в БД об абоненте
PROCEDURE PERSON(ID VARCHAR2) IS
cursor fio is select ФИО f1 from TEL_SPIS where ROWID=ID;
cursor prs(fio VARCHAR2) is
select ПОДРАЗДЕЛЕНИЕ f1, ПОДР f2, ДОЛЖНОСТЬ f3, МЕСТО f4, "Сл# телефон" f5
from TEL_SPIS where ФИО=fio order by 1,2;
cursor zv(fio VARCHAR2) is
select distinct ЗВАНИЕ f1 from TEL_SPIS where ФИО=fio;
cursor dt(fio VARCHAR2) is
select distinct "Дом# телефон" f1 from TEL_SPIS
where ФИО=fio and "Дом# телефон" is not NULL;
ff VARCHAR2(100);
f1 VARCHAR2(100) := 'dummy';
f2 VARCHAR2(100) := 'dummy';
f3 VARCHAR2(100) := 'dummy';
f4 VARCHAR2(100) := 'dummy';
BEGIN
open fio; fetch fio into ff; close fio;
HEADER('Телефонный справочник НГУ. '||ff);
htp.p('<TABLE WIDTH="100%" CELLPADDING="0" CELLSPACING="0">');
htp.p('<TR><TD ALIGN="CENTER"><FONT SIZE="+3">'||ff||'</FONT>');
htp.p('<TR><TD ALIGN="CENTER">');
For rec in zv(ff) Loop
If zv%ROWCOUNT>1 Then htp.p(', '); End If;
htp.p(rec.f1);
End Loop;
htp.p('</TABLE>');
htp.p('<CENTER>');
For rec in prs(ff) Loop
If f1!=rec.f1 Then
htp.p('<HR>');
f1:=rec.f1;
htp.p('<FONT SIZE="+2"><B>'||rec.f1||'</B></FONT>');
End If;
If f2!=rec.f2 and rec.f2!=rec.f1 Then
f2:=rec.f2;
htp.p('<BR><FONT SIZE="+1">'||rec.f2||'</FONT>');
End If;
If f3!=rec.f3 Then f3:=rec.f3; htp.p('<BR>'||rec.f3); End If;
If f4!=rec.f4 Then
f4:=rec.f4;
htp.p('<BR>'||rec.f4||'<BR>');
Else
htp.p('<BR>');
End If;
htp.p('<FONT SIZE="+2">'||rec.f5||'</FONT>');
End Loop;
For rec in dt(ff) Loop
If dt%ROWCOUNT=1 Then
htp.p('<HR>Дом.тел.: ');
Else
htp.p(', ');
End If;
htp.p(rec.f1);
End Loop;
htp.p('</CENTER>');
FOOTER;
EXCEPTION WHEN OTHERS THEN sqlerror;
END;
-- Выводит форму для ввода условия поиска
PROCEDURE QUERY IS
BEGIN
HEADER('Телефонный справочник НГУ. Поиск.');
htp.p('<CENTER>');
htp.p('<FONT SIZE="+2">Поиск</FONT>');
htp.p('<HR>');
htp.p('<FORM ACTION="'||pkg||'query_name" METHOD="POST">');
htp.p('ФИО : <INPUT TYPE="TEXT" NAME="LETTERS" SIZE="30">');
htp.p('<INPUT TYPE="SUBMIT" VALUE="Выполнить">');
htp.p('<FORM>');
htp.p('</CENTER>');
htp.p('<HR>');
htp.p('<BR>В качестве условия запроса можно задать первые буквы фамилии или шаблон :');
htp.p('<DL>');
htp.p('<DD> _ (подчерк) - заменяет любой символ');
htp.p('<DD> % (процент) - заменяет произвольную последовательность символов');
htp.p('</DL>');
htp.p('<BR><B>Например:</B> "% Сергей С_востьянович"');
FOOTER;
EXCEPTION WHEN OTHERS THEN sqlerror;
END;
-- Список абонентов, удовлетворяющий условию поиска по ФИО
PROCEDURE QUERY_NAME(LETTERS VARCHAR2 DEFAULT NULL) IS
BEGIN
HEADER('Телефонный справочник НГУ. Поиск по ФИО. '||LETTERS);
htp.p('<CENTER>');
htp.p('<FONT SIZE="+2">Результат поиска по ФИО</FONT><BR>');
htp.p('<FONT SIZE="+1">("'||LETTERS||'")</FONT>');
htp.p('</CENTER>');
If LETTERS is NULL Then
htp.p('<H1>Не задано условие для запроса!</H1>');
Else
PHONE_LIST(LETTERS);
End If;
FOOTER;
EXCEPTION WHEN OTHERS THEN sqlerror;
END;
END;