2013-05-06 50 views
0

我不知道我的问题是否足够清晰。我有一个运输公司的数据库,用于存储所有行程的日期和时间,我试图阻止某人在预定出发时间前一小时预订机票,或者在出发日期和时间之后购买机票。 我试过为此创建触发器,但由于某些原因,它不允许我创建符合时间要求的故障单。它给了我一个错误如何解决导致递归问题的Oracle触发器

ERROR at line 1: 
ORA-00036: maximum number of recursive SQL levels (50) exceeded 
ORA-00036: maximum number of recursive SQL levels (50) exceeded 

下面是我的触发代码:

CREATE OR REPLACE TRIGGER validHour 
BEFORE INSERT OR UPDATE 
ON ticket 
FOR EACH ROW 
DECLARE x number; 
BEGIN 
select EXTRACT(DAY FROM (departure - sysdate)) * 1440 + EXTRACT(HOUR FROM (departure - sysdate)) * 60 + EXTRACT(MINUTE FROM (departure - sysdate)) 
into x 
from trip 
where trip.tripid=:new.tripid; 

IF :new.status = 'Reserved' AND x<= 59 THEN 
    raise_application_error(-20000,'You can only reserve an hour before departure'); 
ELSIF :new.status = 'Purchased' AND x<= 0 THEN 
    raise_application_error(-20000,'You can only purchase before departure'); 
ELSE 
    INSERT INTO ticket(name, lastname, status, reservationid, cardnumber, tripid, seatnum) 
    VALUES(:new.name, :new.lastname, :new.status, :new.reservationid, :new.cardnumber, :new.tripid, :new.seatnum); 
END IF; 

END; 
/

如果这个创建触发器是不正确的方法,我怎么回事,能做到这一点?

+0

你的插入触发器应该调用插入吗? – mconlin 2013-05-06 02:11:29

+1

'选择(出发 - 系统日期)* 60 * 24从旅行'将给你这些日期之间的分钟数量,无需'提取' – 2013-05-06 02:35:18

+0

@beherenow我不知道!我努力获得这个价值,我希望我知道这很容易。谢谢(你的)信息! – 2013-05-06 03:10:33

回答

4

这是因为您在触发器中插入了另一行。如果你不提出这个错误,那就放手吧。插入将继续,因为触发器被触发,因为插入的在第一位。您不必再次插入相同的数据。

通过在ticket中插入另一行,再次触发触发器等,从而导致堆栈异常。

此:

IF :new.status = 'Reserved' AND x<= 59 THEN 
    raise_application_error(-20001, 'You can only reserve an hour before departure'); 
ELSIF :new.status = 'Purchased' AND x<= 0 THEN 
    raise_application_error(-20002, 'You can only purchase before departure'); 
END IF; 

就足够了。 (我纠正了错误号)

+0

谢谢! :)这是诀窍。 – 2013-05-06 03:09:12

2

您的触发器被递归调用,因为您正在其中执行另一个插入。 取出插入。 BEFORE INSERT触发器被称为插入/更新DML的一部分。如果您的验证通过,那么您无需执行其他任何操作,因为插入操作会完成。

+0

谢谢!这是诀窍。我不知道检查后没有必要插入。 – 2013-05-06 03:08:22