Получил этот вопрос на экзамене, но получил ошибку от триггера. Пожалуйста помоги.
Вопрос
клиент (cust_id, CUST_NAME, адрес)
rent_info (cust_id, date_out, date_due_in, date_returned, штраф)
rented_video (CUST_ID, no_of_videos)
Выпуск должен быть текущей датой, а срок должен составлять 7 дней после даты выпуска. Когда клиент возвращает видео, таблица rent_info должна содержать cust_id, date_out, date_due_in. Триггер используется для вставки данных в таблицу rent_info. Следующая проверка должна быть выполнена перед вставкой данных.
Клиенту не разрешено снимать более 3 видео в одну и ту же дату. Когда видео возвращается, дата возврата обновляется. И штраф рассчитывается, если таковые имеются.
Штраф рассчитывается по
За первые три дня задержки РТС
10 в день
За следующие три дня
задержка 20 рупий в день
После шести дат взимается штраф в размере
30 рупий в день
Напишите процедуру / триггер для выполнения операции обновления.
Я решил это так.
Сделано три стола:
create table customer(
cust_id number(4),
cust_name varchar2(8),
address varchar2(8)
);
create table rent_info(
cust_id number(4),
date_out date,
date_due_in date,
date_returned date,
fine number(10)
);
create table rented_video(
cust_id number(4),
no_vid number(4)
);
Порядок принятия книги
create or replace procedure take_proc(c_id in int,d_out in date) is
val number(3) :=0;
begin
insert into rent_info values(c_id,d_out,d_out+7,NULL,0);
update rented_video set no_vid=no_vid+1 where cust_id=c_id;
--val := select count(date_out) from rent_info where (date_out='12-jan-2010');
--dbms_output.put_line('Values is '||val);
end;
/
Порядок возврата книги
create or replace procedure return_proc(c_id in int,d_ret in date) is
val number(3) :=0;
begin
update rented_video set no_vid=no_vid-1 where cust_id=c_id;
update rent_info set date_returned=d_ret where cust_id=c_id;
--insert into rent_info values(c_id,d_out,d_out+7,NULL,0);
update rented_video set no_vid=no_vid-1 where cust_id=c_id;
--val := select count(date_out) from rent_info where (date_out='12-jan-2010');
--dbms_output.put_line('Values is '||val);
end;
/
Триггер для обновления Fine при возврате книги
create or replace trigger ret_trig
before update on rent_info
for each row
declare
tfine number(7) := 0;
temp number(7) := 0;
rdate date;
dudate date;
cid number(4);
begin
--select date_returned into rdate from rent_info;
--select date_due_in into dudate from rent_info;
--select cust_id into cid from rent_info;
--if (rdate- dudate) <=3 then
--temp := rdate- dudate;
--tfine := tfine+ temp * 10;
--end if;
if (:new.date_returned-:old.date_due_in ) <=3 then
temp := :new.date_returned-:old.date_due_in;
tfine := tfine+ temp * 10;
dbms_output.put_line('Fine Values is '|| tfine);
elsif (:new.date_returned-:old.date_due_in ) <=6 then
temp := :new.date_returned-:old.date_due_in;
tfine := tfine+ 3 * 10;
tfine := tfine+ 20*(temp-3);
dbms_output.put_line('Fine Values is '|| tfine);
else
temp := :new.date_returned-:old.date_due_in;
tfine := tfine+ 3 * 10;
tfine := tfine+ 3 * 20;
tfine := tfine+ 30*(temp-6);
dbms_output.put_line('Fine Values is '|| tfine);
end if;
--update rent_info set fine=fine+tfine where cust_id=:old.cust_id;
end;
/
Я мог бы правильно рассчитать штраф, но не смог обновить его до таблицы rent_info (прокомментирована последняя строка триггера, который выполняет обновление).
Думаю, я допустил логическую ошибку при создании триггера. Подскажите пожалуйста как правильно решить проблему.
Пример значений для вставки
insert into customer values(1,'john','abc h');
insert into customer values(2,'joseph','cde h');
insert into rented_video values(1,0);
insert into rented_video values(2,0);
exec take_proc(1,'12-jan-2010');
exec take_proc(2,'13-jan-2010');
exec return_proc(1,'16-jan-2010');
exec return_proc(2,'29-jan-2010');