Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
маркин.doc
Скачиваний:
3
Добавлен:
01.03.2025
Размер:
928.26 Кб
Скачать

6. Скрипт по созданию хранимых процедур

  1. Разработать хранимую процедуру, которая за заданный период времени выводит список сотрудников-инструкторов с указанием количества часов проведенных занятий, общей суммы средств, полученных от клиентов, и количества клиентов, посетивших их занятия.

CREATE OR ALTER PROCEDURE REGISTERP (

date1 date, --дата начала

date2 date) –дата конца

returns (

out_fio varchar(50),--фио сотрудника

kol integer, --количество занятий

sumka numeric(15,2), --общая сумма за занятия

kol_chel integer) – количество человек на занятиях

as

declare variable res_chel integer; --результирующее число человек

declare variable itime integer; --текущий временной интервал

declare variable res_sum numeric(15,2); --результирующая сумма

declare variable cur_sum numeric(15,2); --текущая сумма

declare variable skidka integer; --значение скидки

declare variable ab integer; --текущий абонемент

declare variable cur_chel integer; --текущее число человек

declare variable w_fio varchar(50); --фио сотрудника

declare variable cur_kol integer; --текущее количество занятий

declare variable hall integer; --текущий код помещения

declare variable res_kol integer; --результирующее количество занятий

declare variable w_kod integer; --код сотрудника

begin

/*выбираем построчно сотрудников из таблицы "Сотрудники", чья должность-инструктор*/

for select W.id_worker, W.FIO from workers w where w.id_job=

(select j.id_job from Jobs J where j.name='Инструктор')

/*в переменную w_kod запоминается текущий код сотрудника, в w_fio-ФИО сотрудника*/

into :w_kod, :w_fio

do

begin

/*обнуляем переменные перед операцией суммы*/

res_chel=0;

res_kol=0;

sumka=0;

res_sum=0;

cur_sum=0;

/*выбираем построчно код интервала планирования и код помещения (оба поля сотсавляют уникальной код занятия), где занятие проводит выбранный сотрудник с кодом w_kod*/

for select T.id_itime, T.id_hall from Timetable T where T.id_worker= :w_kod

/*в переменную itime запоминается текущий код интервала планирования, в hall-код помещения*/

into :itime, :hall

do

begin

/*для каждого абонемента, удовлетворяющим заданным интервалам планирования и помещения*/

for select r.id_abonement from register r where r.id_itime=:itime and r.id_hall=:hall

/*дата регистрации должна находиться в диапозоне заданного значеия отрезка времени*/

and r.Date_Register BETWEEN :Date1 AND :Date2

/*в переменную ab записывается код абонемента текущий*/

into :ab

do

begin

/*выбирается значение скидки для каждого абонемента*/

select d.discount from discounts d where

d.id_discount=(select a.id_discount from abonements a where

a.id_abonement=:ab)

/*в переменную skidka записывается значение скидки для текущего абонемента ab*/

into :skidka;

/*выбирается цена для текущего занятия*/

select p.price from price_list p where p.id_worker=:w_kod and

p.id_service=

(select t.id_service from timetable t where t.id_hall=:hall and

t.id_itime=:itime)

/*цена за занятие*/

into :cur_sum;

/*если скидка не равна 0, то скидка вычитается из цены, если равно 0, то цена не изменятеся*/

if (:skidka is not null) then cur_sum=:cur_sum-:cur_sum*:skidka/100;

else cur_sum=:cur_sum;

/*результирующая сумма за абонементы*/

res_sum=:res_sum+:cur_sum;

end

/*подсчет числа занятий и числа клиентов на занятиях*/

select count(distinct r.id_itime), count(r.id_itime) from register r where

r.id_itime=:itime and r.id_hall=:hall

and r.Date_Register BETWEEN :Date1 AND :Date2

/*запоминается в cur_kol количество проведенных занятий, в cur_chel количество человек*/

into :cur_kol, :cur_chel;

/*подсчет общего числа занятий и занимающихся для каждого сотрудника*/

res_kol=:res_kol+:cur_kol ;

res_chel=:res_chel+:cur_chel;

end

/*выходные переменные*/

out_fio=:w_fio;

kol=:res_kol;

kol_chel=:res_chel;

sumka=:res_sum;

res_sum=0;

cur_sum=0;

res_kol=0;

res_chel=0;

suspend;

end

end

  1. Разработать хранимую процедуру, которая для заданного помещения за заданный период времени формирует расписание проводимых занятий с указанием ФИО сотрудника-инструктора, его должность, наименование оказанной услуги.

/*создание вспомогательной процедуры для вычисления дня недели по заданной дате*/

CREATE PROCEDURE WEEK_D (

date1 date)

returns (

day_week varchar(11)) –-возвращает значение дня недели

as

declare variable kol_d bigint;

declare variable i smallint;

BEGIN

/*высчитывается разница в днях между первым днем года и введенной датой*/

kol_d=datediff(day, cast('01.01.2008' as date),:date1);

/*находится остаток от деления количества дней на 7*/

i=kol_d - cast((kol_d/7) as integer)*7;

/*по полученному коду i рассчитывается день недели, иссходя из того, что 01.01.2008 это вторник*/

if (i='0') then day_week='Вторник';

if (i='1') then day_week='Среда';

if (i='2') then day_week='Четверг';

if (i='3') then day_week='Пятница';

if (i='4') then day_week='Суббота';

if (i='5') then day_week='Воскресенье';

if (i='6') then day_week='Понедельник';

END;

/*создание процедуры составления расписания по заданному интервалу времени за заданное помещение*/

CREATE PROCEDURE HALLP (

hall varchar(20),

date1 date,

date2 date)

returns (

data date, --число

worker varchar(30), --фио сотрудника

job varchar(20), --должность

service varchar(20), --наименование услуги

week varchar(11), --день недели

times varchar(5)) --время

as

declare variable itime integer; --текущий интервал планирования

declare variable week_day varchar(11); --день недели

declare variable i date; --переменная для изменения текущего числа

BEGIN

/*переменной i присваиваем текущую дату*/

I=:date1;

/*пока текущая дата не превысит последнюю дату диапозона выполнять цикл*/

WHILE (I<=:date2)

DO BEGIN

/*вызов процедуры week_d для получения из даты день недели*/

execute procedure week_d(:i) returning_values week_day;

/*построчно для каждого интервала планирования по определенной дате(по дню недели)

выбирать день недели равный переменной week_day*/

FOR SELECT T.id_itime FROM interval_time T

WHERE T.week=:week_day

/*itime хранит значение текущего интервала планирования для даты i*/

INTO :ITIME

DO

BEGIN

/*построчно для каждой записи составлять расписание занятий*/

FOR SELECT :i,

/*выбор фио сотрудника*/

(SELECT W.fio FROM workers W WHERE

W.id_worker=S.id_worker),

/*выбор долдности*/

(select J.name FROM jobs J WHERE J.id_job=

(SELECT G.id_job FROM WORKERS G WHERE

G.id_worker=S.id_worker)),

/*выбор наименования услуги*/

(SELECT Z.name from services Z WHERE Z.id_service=S.id_service),

/*выбор дня недели*/

(SELECT O.week from interval_time O WHERE

O.id_itime=S.id_itime),

/*выбор рабочего времени*/

(SELECT O.times from interval_time O WHERE

O.id_itime=S.id_itime)

FROM timetable S

/*отбор строк для текущего помещения*/

WHERE S.id_hall=(SELECT H.id_hall FROM HALLS H WHERE H.name=:hall)

AND S.id_itime=:ITIME

/*выходные переменные*/

into :data,:worker,:job,:service,:week,:times

DO SUSPEND;

END

/*увеличение даты на 1 день*/

I=dateadd(day,1,:I);

END

END