使用 PL/SQL 块创建触发器时出错

Posted

技术标签:

【中文标题】使用 PL/SQL 块创建触发器时出错【英文标题】:Error while creating trigger using PL/SQL block 【发布时间】:2020-03-22 11:09:03 【问题描述】:

问题: fl_schedule(flno, 出发, dtime, 到达, atime, 价格)。

仅当航班号 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

【问题讨论】:

【参考方案1】:

为了能够在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;
/

没有 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 ..ETC。如果是日期时间类型变量,则允许,但不允许 weekday

【讨论】:

以上是关于使用 PL/SQL 块创建触发器时出错的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL练习命名块: 存储过程函数触发器包

PL/SQL Oracle 错误处理

Oracle --- 存储过程函数包游标触发器

Oracle --- 存储过程函数包游标触发器

Oracle --- 存储过程函数包游标触发器

PL/SQL结构