0

私の質問が十分に明確かどうかわかりません。すべての旅行の日時を保存する運送会社のデータベースがあり、誰かが出発予定時刻の 1 時間前にチケットを予約したり、出発日時以降にチケットを購入したりするのを防ごうとしています。このためのトリガーを作成しようとしましたが、時間要件に準拠している場合、何らかの理由でチケットを作成できません。それは私にエラーを与える

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 に答える