使用 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 CX­7520 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 CX­7520 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 CX­7520 can be scheduled only on Tuesday, Friday and Sunday.');
 END IF;
END;
/
  • 使用包含 NLS_DATE_LANGUAGE 选项的日期缩写。 否则会遇到意想不到的情况。
  • 显示的错误源于在 EXTRACT() 函数中使用 weekday,其中允许对日期类型变量使用 daymonthyear,还有 hourminutesecond 等。如果是 datetime 类型的变量是允许的,但是 not weekday