Oracle 11g 触发器错误 - ORA-00923:未在预期位置找到 FROM 关键字

Oracle 11g Trigger Error - ORA-00923: FROM keyword not found where expected

我对 Oracle SQL(特别是 Oracle 11g SQL)还是很陌生。我正在尝试编写触发器,但似乎无法解决所有错误。当前,当我尝试执行下面列出的 SQL 时,出现此错误:

Error at line 12: PL/SQL: ORA-00923: FROM keyword not found where expected

1. CREATE OR REPLACE TRIGGER course_assignment_trigger
2. AFTER INSERT ON Assign FOR EACH ROW
3. DECLARE

这是SQL我有:

CREATE OR REPLACE TRIGGER course_assignment_trigger
AFTER INSERT ON Assign FOR EACH ROW
DECLARE
   tooManyCourses EXCEPTION;
   notQualified EXCEPTION;
   assignedBeforeQualified EXCEPTION;
   assignedCourseCount int;
   qualifiedRowCount int;
   PRAGMA EXCEPTION_INIT( tooManyCourses, -20001 );
   PRAGMA EXCEPTION_INIT( notQualified, -20001 );
   PRAGMA EXCEPTION_INIT( assignedBeforeQualified, -20001 );


BEGIN
   SELECT assignedCourseCount = COUNT(*) FROM Assign where Fid = :new.Fid;
   IF assignedCourseCount  >= 3
   THEN
       RAISE tooManyCourses;
   END IF;

   SELECT qualifiedRowCount = COUNT(*) FROM Qualify where Fid = :new.Fid and Cid = :new.Cid;
   IF qualifiedRowCount = 0
   THEN
       RAISE notQualified;
   END IF;

   IF(:new.assignDate < (select qualifyDate from Qualify where Fid = :new.Fid and Cid = :new.Cid))
   THEN
       RAISE unacceptedDateOfQualification;
   END IF;

EXCEPTION
   WHEN tooManyCourses THEN
       DBMS_OUTPUT.PUT_LINE('Cannot assign faculty to more than 3 courses.');

   WHEN notQualified THEN
       DBMS_OUTPUT.PUT_LINE('Faculty is not qualified to teach the course.');

   WHEN assignedBeforeQualified THEN
       DBMS_OUTPUT.PUT_LINE('Date of qualification must be before date of assignment.');

END;

你快到了。

语法是:

SELECT column_identifier
INTO   plsql_variable
FROM   table
-- ...

而你 RAISE unacceptedDateOfQualification 当你将异常声明为 assignedBeforeQualified 并且需要给每个异常一个不同的错误号。但是,您几乎肯定不想引发自定义异常并在同一个触发器中捕获它们并输出到控制台,因为它不会阻止 INSERT 的发生;你想要 RAISE_APPLICATION_ERROR 与你的自定义错误消息并想要这样做 BEFORE INSERT.

像这样:

CREATE OR REPLACE TRIGGER course_assignment_trigger
BEFORE INSERT ON Assign FOR EACH ROW
DECLARE
   assignedCourseCount int;
   qualifiedRowCount int;
   qualifyDt DATE;
BEGIN
   SELECT COUNT(*)
   INTO   assignedCourseCount
   FROM   Assign
   where Fid = :new.Fid;
   
   IF assignedCourseCount  >= 3
   THEN
       RAISE_APPLICATION_ERROR( -20001, 'Cannot assign faculty to more than 3 courses.');
   END IF;

   SELECT COUNT(*)
   INTO   qualifiedRowCount
   FROM   Qualify
   where  Fid = :new.Fid
   and    Cid = :new.Cid;

   IF qualifiedRowCount = 0
   THEN
       RAISE_APPLICATION_ERROR( -20002, 'Faculty is not qualified to teach the course.');
   END IF;

   select MIN(qualifyDate)
   INTO   qualifyDt
   from   Qualify
   where  Fid = :new.Fid
   and    Cid = :new.Cid;
   
   IF :new.assignDate < qualifyDt
   THEN
       RAISE_APPLICATION_ERROR( -20003, 'Date of qualification must be before date of assignment.' );
   END IF;
END;
/

如果你有表格:

CREATE TABLE assign (
  FID number,
  CID number,
  assignDate DATE
);

CREATE TABLE qualify (
  FID number,
  CID number,
  qualifyDate DATE
);

然后:

INSERT INTO assign VALUES ( 1, 1, DATE '2020-01-01' );

引发异常:

ORA-20002: Faculty is not qualified to teach the course.
ORA-06512: at "FIDDLE_BLJCMOGDEOXTZOEWHDDA.COURSE_ASSIGNMENT_TRIGGER", line 24
ORA-04088: error during execution of trigger 'FIDDLE_BLJCMOGDEOXTZOEWHDDA.COURSE_ASSIGNMENT_TRIGGER'

然后:

INSERT INTO qualify VALUES ( 1, 1, DATE '2020-01-01' );
INSERT INTO assign VALUES ( 1, 1, DATE '2020-01-01' );

有效但是:

INSERT INTO assign VALUES ( 1, 1, DATE '2019-01-01' );

引发异常:

ORA-20003: Date of qualification must be before date of assignment.
ORA-06512: at "FIDDLE_BLJCMOGDEOXTZOEWHDDA.COURSE_ASSIGNMENT_TRIGGER", line 35
ORA-04088: error during execution of trigger 'FIDDLE_BLJCMOGDEOXTZOEWHDDA.COURSE_ASSIGNMENT_TRIGGER'

和:

INSERT INTO assign VALUES ( 1, 1, DATE '2020-01-01' );
INSERT INTO assign VALUES ( 1, 1, DATE '2020-01-01' );
INSERT INTO assign VALUES ( 1, 1, DATE '2020-01-01' );

插入行的第 2 个和第 3 个副本,但第 4 个副本引发异常:


ORA-20001: Cannot assign faculty to more than 3 courses.
ORA-06512: at "FIDDLE_BLJCMOGDEOXTZOEWHDDA.COURSE_ASSIGNMENT_TRIGGER", line 13
ORA-04088: error during execution of trigger 'FIDDLE_BLJCMOGDEOXTZOEWHDDA.COURSE_ASSIGNMENT_TRIGGER'

db<>fiddle here