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;