【发布时间】:2023-03-16 15:25:02
【问题描述】:
在考试中得到了这个问题,但触发器出错。请帮忙。
问题
客户(cust_id、cust_name、地址) 租金信息(cust_id,date_out,date_due_in,date_returned,罚款) 租用视频(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');
【问题讨论】:
标签: database stored-procedures plsql triggers