0

我不知道我的问题是否足够清楚。我有一个存储所有旅行日期和时间的运输公司的数据库,我试图防止有人在预定出发时间前一小时预订机票或在出发日期和时间之后购买机票。我已经尝试为此创建一个触发器,但由于某种原因,如果它符合时间要求,它不允许我创建票证。它给了我一个错误

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;
/

如果为此创建触发器不是正确的方法,我还能怎么做?

4

2 回答 2

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;

足够。(我更正了错误编号)

于 2013-05-06T02:10:05.590 回答
2

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

于 2013-05-06T02:11:42.713 回答