Функции и процедуры
This commit is contained in:
108
report.tex
108
report.tex
@@ -563,4 +563,112 @@ grant usage, select on sequence shot_series_id_shot_series_seq to edit_user;
|
|||||||
\end{tabularx}
|
\end{tabularx}
|
||||||
\end{table}
|
\end{table}
|
||||||
|
|
||||||
|
|
||||||
|
\subsection{Работа 4: Создание функций и процедур}
|
||||||
|
\textbf{Задача:} Создать функцию и использовать её в запросе. Создать процедуру, которая будет создавать новые записи в таблицах по определённым условиям.
|
||||||
|
|
||||||
|
\textbf{Формулировка задачи:} Создать функцию \texttt{convert\_to\_initials}, которая будет получать на вход строки с ФИО, а возвращать строку с инициалами. Создать процедуру \texttt{create\_participant\_request}, которая по заданной информации о соревновании, спортсмене и дивизионе будет создавать заявку на участие в соревновании.
|
||||||
|
|
||||||
|
Код определения функции \texttt{convert\_to\_initials} представлен на Рис.~\ref{lst:convert_to_initials}. Функция принимает на вход три параметра типа \texttt{varchar}: \texttt{p\_name} -- имя, \texttt{p\_surname} -- фамилия, \texttt{p\_patronymic} -- отчество. Возвращает также \texttt{varchar} -- строку с инициалами. Если имя или фамилия не заданы, функция возвращает пустую строку. Функция также отдельно обрабатывает случай, когда не задано отчество, в таком случае инициалы будут состоять только из первой буквы имени и фамилии. Код запроса с использованием этой функции представлен на Рис.~\ref{lst:convert_query}, а результат его выполнения на Рис.~\ref{fig:conver_result}.
|
||||||
|
|
||||||
|
\newpage
|
||||||
|
\begin{lstlisting}[mathescape=true, caption={Код определения функции \texttt{convert\_to\_initials}.}, label={lst:convert_to_initials}]
|
||||||
|
create or replace function convert_to_initials(
|
||||||
|
p_name varchar,
|
||||||
|
p_surname varchar,
|
||||||
|
p_patronymic varchar
|
||||||
|
) returns varchar as $$
|
||||||
|
begin
|
||||||
|
if p_name is null or p_name = '' or p_surname is null or p_surname = '' then
|
||||||
|
return '';
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if p_patronymic is null or p_patronymic = '' then
|
||||||
|
return concat(substring(p_name from 1 for 1), '. ', p_surname);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
return concat(substring(p_patronymic from 1 for 1), '. ', substring(p_name from 1 for 1), '. ', p_surname);
|
||||||
|
end;
|
||||||
|
$$ language plpgsql;
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\begin{lstlisting}[mathescape=true, caption={Код запроса с использованием функции \texttt{convert\_to\_initials}.}, label={lst:convert_query}]
|
||||||
|
select
|
||||||
|
id_judge,
|
||||||
|
convert_to_initials (name, surname, patronymic),
|
||||||
|
name,
|
||||||
|
surname,
|
||||||
|
patronymic
|
||||||
|
from
|
||||||
|
judge
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\begin{figure}[h]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=1\linewidth]{img/conver_result.png}
|
||||||
|
\caption{Первые десять записей результата выполнения запроса с применением функции \texttt{convert\_to\_initials}.}
|
||||||
|
\label{fig:conver_result}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
Код определения процедуры \texttt{create\_participant\_request} представлен на Рис.~\ref{lst:procedure}. Процедура принимает на вход пять параметров типа \texttt{varchar}: \texttt{p\_name} -- имя спортсмена, \texttt{p\_surname} -- фамилия спортсмена, \texttt{p\_gender} -- пол спортсмена, \texttt{p\_competition\_title} -- название соревнования, \texttt{p\_division\_title} -- название дивизиона. Внутри процедуры сначала проверяется существование дивизиона в базе данных по переданному названию. Если дивизион не найден, выбрасывается ошибка. Затем проверяется существование соревнования. Если соревнование не существует, оно создаётся. Далее проверяется, существует ли спортсмен с указанными именем, фамилией и полом. Если спортсмен не найден, то создаётся новая запись о спортсмене. В конце создаётся заявка участника с указанием данных спортсмена, соревнования и дивизиона.
|
||||||
|
|
||||||
|
\begin{lstlisting}[mathescape=true, caption={Код определения процедуры \texttt{create\_participant\_request}.}, label={lst:procedure}]
|
||||||
|
create or replace procedure create_participant_request(
|
||||||
|
p_name varchar(100),
|
||||||
|
p_surname varchar(100),
|
||||||
|
p_gender varchar(10),
|
||||||
|
p_competition_title varchar(100),
|
||||||
|
p_division_title varchar(100)
|
||||||
|
)
|
||||||
|
language plpgsql
|
||||||
|
as $$
|
||||||
|
declare
|
||||||
|
v_id_sportsman integer;
|
||||||
|
v_id_competition integer;
|
||||||
|
v_id_division integer;
|
||||||
|
begin
|
||||||
|
-- проверка существования дивизиона
|
||||||
|
select id_division into v_id_division
|
||||||
|
from division
|
||||||
|
where title = p_division_title
|
||||||
|
limit 1;
|
||||||
|
|
||||||
|
if not found then
|
||||||
|
raise exception 'Дивизиона % не существует', p_division_title;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- проверка существования соревнования
|
||||||
|
select id_competition into v_id_competition
|
||||||
|
from competition
|
||||||
|
where title = p_competition_title
|
||||||
|
limit 1;
|
||||||
|
|
||||||
|
-- если соревнование не существует, создать его
|
||||||
|
if not found then
|
||||||
|
insert into competition (title)
|
||||||
|
values (p_competition_title)
|
||||||
|
returning id_competition into v_id_competition;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- проверка существования спортсмена
|
||||||
|
select id_sportsman into v_id_sportsman
|
||||||
|
from sportsman
|
||||||
|
where name = p_name and surname = p_surname and gender = p_gender
|
||||||
|
limit 1;
|
||||||
|
|
||||||
|
-- если спортсмен не существует, создать его
|
||||||
|
if not found then
|
||||||
|
insert into sportsman (name, surname, gender)
|
||||||
|
values (p_name, p_surname, p_gender)
|
||||||
|
returning id_sportsman into v_id_sportsman;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- создание заявки участника
|
||||||
|
insert into participant_request (name, surname, gender, is_registered, id_competition, id_sportsman, id_division)
|
||||||
|
values (p_name, p_surname, p_gender, false, v_id_competition, v_id_sportsman, v_id_division);
|
||||||
|
end;
|
||||||
|
$$;
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
|
||||||
\end{document}
|
\end{document}
|
||||||
Reference in New Issue
Block a user