【发布时间】:2014-03-08 20:56:13
【问题描述】:
我一直在尝试获得一个基本上会运行这样的约束的触发器; 约束(日期
它将一个表格(比赛)中的日期与另一表格(会议)中的日期进行比较。我知道我可以使用外键来实现这一点,但我很确定会获得更多我需要使用触发器的标记。
到目前为止,我得到了这个:
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')
【问题讨论】:
-
race上的INSERT或UPDATE是否来自MEETING表上定义的另一个触发器? -
Mihai,我在使用 BEFORE 时也遇到了同样的错误。 @JustinCave,我不这么认为 - 这是我唯一的触发器。
-
发布一个可重现的测试用例。发布 DDL 以创建两个表。如果需要该数据来重现问题,请发布 DML 以填充表。发布您正在使用的导致触发器触发的语句。
-
@Naffel - 缺少一些东西,您提供的代码不会给出该错误。查询
user_triggers和/或user_objects,看看是否有你忘记的东西。也许是您为之前的尝试创建的触发器? -
“我很肯定会得到更多我需要使用触发器的分数” 做出糟糕的设计决定的可怕原因。触发器很少是正确的实现。