在PLSQL中触发问题

时间:2014-03-08 20:56:13

标签: oracle plsql triggers

我一直试图获得一个基本上会运行这样的约束的触发器; CONSTRAINT(日期< = Meeting.EndDate)

将一个表格(种族)中所述的日期与另一个表格(会议)中所述的日期进行比较。我知道我可以使用外键实现这一点,但我确信我需要使用触发器获得更多标记。

到目前为止,我已经得到了这个:

CREATE OR REPLACE TRIGGER race_date_trg    
AFTER INSERT OR UPDATE
  ON RACE
  FOR EACH ROW
  DECLARE
    MEETING_ENDDATE DATE;
    STARTDATE race.racedate%TYPE;
  BEGIN
    SELECT ENDDATE INTO MEETING_ENDDATE FROM meeting;
    IF STARTDATE > MEETING_ENDDATE THEN
      RAISE_APPLICATION_ERROR(-20000, 'Wrong start date!');
    END IF;
  end race_date_trg;

它编译得很好,但是当我尝试用可以引发错误的东西填充表格时,我得到了这个:

Error report:
SQL Error: ORA-04091: table SE488.MEETING is mutating, trigger/function may not see it
ORA-06512: at "SE488.RACE_DATE_TRG", line 5
ORA-04088: error during execution of trigger 'SE488.RACE_DATE_TRG'
04091. 00000 -  "table %s.%s is mutating, trigger/function may not see it"
*Cause:    A trigger (or a user defined plsql function that is referenced in
           this statement) attempted to look at (or modify) a table that was
           in the middle of being modified by the statement which fired it.
*Action:   Rewrite the trigger (or function) so it does not read that table.

感谢您的帮助。

创建表格:

CREATE TABLE Meeting
(
MeetLocation varchar2(60),
StartDate date,
EndDate date,
MeetName varchar2(60)
);

CREATE TABLE Race
(
RaceID NUMBER,
RaceLocation varchar2(60),
MeetingStart date,
RaceDate date,
RaceTime timestamp(0), 
RaceName varchar2(60),
RaceType varchar2(8),
MinAge numeric(2),
MaxAge numeric(2),
Sex varchar2(2) NULL
);

填充它们:

  INTO Meeting (MeetLocation,StartDate,EndDate,MeetName)
    values('Talbot','30-Jul-05','07-Aug-05','Midlands Derby')
  INTO Meeting (MeetLocation,StartDate,EndDate,MeetName)
    values('Ascot','04-Jul-10','07-Aug-10','National Derby')

  INTO Race (RaceID,RaceLocation,MeetingStart,RaceDate,RaceTime,RaceName,RaceType,MinAge,MaxAge,Sex)
    values('1','Talbot','20-Jul-05','31-Jul-05',to_date('2005/07/31:12:00:00PM', 'yyyy/mm/dd:hh:mi:sspm'),'600m Dash','Flat','2','10','M')
  INTO Race (RaceID,RaceLocation,MeetingStart,RaceDate,RaceTime,RaceName,RaceType,MinAge,MaxAge,Sex)
    values('2','Talbot','30-Jul-05','01-Aug-05',to_date('2005/08/01:01:10:00PM', 'yyyy/mm/dd:hh:mi:sspm'),'1km Hurdles','Flat','6','12','F')

1 个答案:

答案 0 :(得分:0)

CREATE OR REPLACE TRIGGER race_date_trg
BEFORE INSERT OR UPDATE ON RACE
FOR EACH ROW
DECLARE
    meet_date date;
    start_date date := :new.RaceDate;
BEGIN
    SELECT StartDate INTO meet_date FROM meeting WHERE MeetLocation = :new.RaceLocation;
    IF start_date > meet_date THEN
        RAISE_APPLICATION_ERROR(-20000, 'Wrong start date!');
    END IF;
END race_date_trg;
/

我认为你想要引发错误或异常。当有人插入或更新表竞赛时,如果开始日期(来自表竞赛)低于满足日期(来自表会议)。 :d