首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PL/SQL触发器产生错误?

PL/SQL触发器产生错误?
EN

Stack Overflow用户
提问于 2011-04-08 04:36:53
回答 2查看 211关注 0票数 0

为考试准备了这个问题,但却被触发了错误。请帮帮忙。

问题

客户(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段视频。返回视频时,返回日期将被更新。如果有的话罚款是计算出来的。

罚款是由

  1. 对前三天的延迟卢比,每天10卢比,
  2. ,对后续3天的延迟卢比,每天20卢比,
  3. ,6天后的罚款,每天30卢比,

编写用于执行更新操作的过程/触发器。

我就这样解决了。

制作了三张桌子:

代码语言:javascript
复制
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)

);

取书程序

代码语言:javascript
复制
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;

/

返回图书的过程

代码语言:javascript
复制
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;

/

触发器用于在图书返回时更新

代码语言:javascript
复制
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表(触发器的最后一行,它会对更新进行注释)。

我想我在触发创造上犯了一些逻辑上的错误。请告诉我如何正确地解决这个问题。

要插入的示例值

代码语言:javascript
复制
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');
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-08 20:35:23

你为什么要用扳机?您正在通过开发这些过程来构建一个非常清晰的API,但随后您将代码插入触发器中。为什么不将这一逻辑融入return_proc以使事情变得更加明显呢?

票数 0
EN

Stack Overflow用户

发布于 2011-04-08 06:11:26

在行级触发器中,只需执行赋值到:NEW -就可以更改列的值,而不是发出UPDATE语句。例如:

代码语言:javascript
复制
:NEW.fine := :OLD.fine + tfine;
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5590492

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档