使用 PL/SQL 块创建触发器时出错
Error while creating trigger using PL/SQL block
问题:
fl_schedule(flno, departs, dtime, arriving, atime, price).
创建一个触发器,仅当航班号 CX7520 安排在周二、周五和周日时才允许插入或更新。
CREATE OR REPLACE TRIGGER flightsch_day
BEFORE INSERT OR UPDATE ON fl_schedule
FOR EACH ROW
WHEN (NEW.flno LIKE 'CX7520')
DECLARE
day NUMBER;
BEGIN
day:=EXTRACT(weekday FROM :NEW.departs);
IF day NOT IN(0,2,5) THEN
RAISE_APPLICATION_ERROR(-20000,'Flight number CX7520 can be scheduled only on Tuesday, Friday and Sunday.');
END IF;
END;
/
错误:
SQL> SHOW ERRORS;
Errors for TRIGGER FLIGHTSCH_DAY:
LINE/COL ERROR
-------- -----------------------------------------------------------------
4/10 PLS-00122: FROM as separator is allowed only with specific
built-in functions
为了能够在 FOR EACH ROW
之后使用 WHEN (NEW.flno = 'CX7520')
,个别列 flno
需要 UPDATE OF flno
CREATE OR REPLACE TRIGGER flightsch_day
BEFORE INSERT OR UPDATE OF flno ON fl_schedule
FOR EACH ROW
WHEN (NEW.flno = 'CX7520')
DECLARE
BEGIN
IF TO_CHAR(:NEW.departs,'Dy','NLS_DATE_LANGUAGE=English') NOT IN ('Tue','Fri','Sun') THEN
RAISE_APPLICATION_ERROR(-20000,'Flight number CX7520 can be scheduled only on Tuesday, Friday and Sunday.');
END IF;
END;
/
or 没有 WHEN..
子句,将 :NEW.flno = 'CX7520'
带入 IF
语句:
CREATE OR REPLACE TRIGGER flightsch_day
BEFORE INSERT OR UPDATE ON fl_schedule
FOR EACH ROW
DECLARE
BEGIN
IF NOT ( TO_CHAR(:NEW.departs,'Dy','NLS_DATE_LANGUAGE=English') IN ('Tue','Fri','Sun')
AND :NEW.flno = 'CX7520' ) THEN
RAISE_APPLICATION_ERROR(-20000,'Flight number CX7520 can be scheduled only on Tuesday, Friday and Sunday.');
END IF;
END;
/
- 使用包含
NLS_DATE_LANGUAGE
选项的日期缩写。
否则会遇到意想不到的情况。
- 显示的错误源于在
EXTRACT()
函数中使用 weekday
,其中允许对日期类型变量使用 day
、month
、year
,还有 hour
、minute
、second
等。如果是 datetime 类型的变量是允许的,但是 not weekday
问题: fl_schedule(flno, departs, dtime, arriving, atime, price).
创建一个触发器,仅当航班号 CX7520 安排在周二、周五和周日时才允许插入或更新。
CREATE OR REPLACE TRIGGER flightsch_day
BEFORE INSERT OR UPDATE ON fl_schedule
FOR EACH ROW
WHEN (NEW.flno LIKE 'CX7520')
DECLARE
day NUMBER;
BEGIN
day:=EXTRACT(weekday FROM :NEW.departs);
IF day NOT IN(0,2,5) THEN
RAISE_APPLICATION_ERROR(-20000,'Flight number CX7520 can be scheduled only on Tuesday, Friday and Sunday.');
END IF;
END;
/
错误:
SQL> SHOW ERRORS;
Errors for TRIGGER FLIGHTSCH_DAY:
LINE/COL ERROR
-------- -----------------------------------------------------------------
4/10 PLS-00122: FROM as separator is allowed only with specific
built-in functions
为了能够在 FOR EACH ROW
之后使用 WHEN (NEW.flno = 'CX7520')
,个别列 flno
UPDATE OF flno
CREATE OR REPLACE TRIGGER flightsch_day
BEFORE INSERT OR UPDATE OF flno ON fl_schedule
FOR EACH ROW
WHEN (NEW.flno = 'CX7520')
DECLARE
BEGIN
IF TO_CHAR(:NEW.departs,'Dy','NLS_DATE_LANGUAGE=English') NOT IN ('Tue','Fri','Sun') THEN
RAISE_APPLICATION_ERROR(-20000,'Flight number CX7520 can be scheduled only on Tuesday, Friday and Sunday.');
END IF;
END;
/
or 没有 WHEN..
子句,将 :NEW.flno = 'CX7520'
带入 IF
语句:
CREATE OR REPLACE TRIGGER flightsch_day
BEFORE INSERT OR UPDATE ON fl_schedule
FOR EACH ROW
DECLARE
BEGIN
IF NOT ( TO_CHAR(:NEW.departs,'Dy','NLS_DATE_LANGUAGE=English') IN ('Tue','Fri','Sun')
AND :NEW.flno = 'CX7520' ) THEN
RAISE_APPLICATION_ERROR(-20000,'Flight number CX7520 can be scheduled only on Tuesday, Friday and Sunday.');
END IF;
END;
/
- 使用包含
NLS_DATE_LANGUAGE
选项的日期缩写。 否则会遇到意想不到的情况。 - 显示的错误源于在
EXTRACT()
函数中使用weekday
,其中允许对日期类型变量使用day
、month
、year
,还有hour
、minute
、second
等。如果是 datetime 类型的变量是允许的,但是 notweekday