创建带条件的触发器

Create Trigger with Condition

我正在尝试创建一个触发器,当学生在没有先决条件的情况下注册课程时,它会在警报 table 中插入值 student_idcourse_id,但我失败了。

这是我的触发器:

CREATE OR REPLACE TRIGGER ALARM_TRIGGER
BEFORE INSERT OR UPDATE OF student_id, course_id ON students_courses
FOR EACH ROW

BEGIN
  insert into alarms(student_id, course_id) values(:NEW.student_id, :NEW.course_id);
END;

表格:

1-课程:有course_id(PK)和course_name。

2-STUDENTS:有 student_id(PK)和 student_name。

3-STUDENTS_COURSES: 每个学生都有他的课程。

4-PREREQUISITE_COURSES:每门课程都有先决条件。

5-ALARMS:当任何学生在没有先决条件的情况下注册课程时触发存储student_id,course_id。

这是课程先决条件的示例 table:

COURSE_NUMBER COURSE_PREREQUISITE
  1 空
  2 1
  3 空
  4 3

如果学生报读了没有先决条件的课程,则先决条件查询结果将为NULL。因此,如果课程有先决条件并且学生已经修完了先决条件,您希望结果相同。这使得后续逻辑更容易。因此,如果该课程有学生 参加的先决条件,则结果将是先决条件的课程 ID(您可以使用它来显示有意义的错误消息)。

如果课程没有先决条件,查询 return NULL 很简单:

select P.COURSE_PREREQUISITE Result
into   RequiredReq
from   Prerequisites P
where  P.COURSE_NUMBER = :new.course_id;

当然,如果有的话,return是先决条件的课程 ID,但我们稍后会处理。现在我们要加入 STUDENTS_COURSES table:

join   STUDENTS_COURSES SC
    on SC.COURSE_NUMBER = P.COURSE_PREREQUISITE
   and SC.Student_ID    = :new.Student_ID

但是,这不会为我们提供所需的一切。首先,如果学生没有参加先决条件,查询将 return 什么都没有,所以我们会得到一个 NO_DATA_FOUND 错误。其次,如果学生 已经 完成了先决条件,它将 return 课程 ID 但在这种情况下我们希望它 return 为 NULL。

让我们看看如果将内连接转换为左外连接会得到什么:

select P.COURSE_PREREQUISITE Result
into   RequiredReq
from   Prerequisites P
left join STUDENTS_COURSES SC
    on SC.COURSE_NUMBER = P.COURSE_PREREQUISITE
   and SC.Student_ID    = :new.Student_ID
where  P.COURSE_NUMBER  = :new.course_id;

这给了我们想要的一切,但不是以正确的方式。如果满足先决条件 not,我们得到 NULL,如果满足 has,我们得到 NULL。所以要改变它,我们只需要在查询中加入一点逻辑:

select case when P.Prerequisite is null then null    --> No prerequisite
            when SC.StudentID is not null then null  --> Prerequisite met
            else P.Prerequisite end Result           --> Prerequisite not met
into   RequiredReq
from   Prerequisites P
left join STUDENTS_COURSES SC
    on SC.COURSE_NUMBER = P.COURSE_PREREQUISITE
   and SC.Student_ID    = :new.Student_ID
where  P.COURSE_NUMBER  = :new.course_id;

现在 NULL 表示课程没有先决条件或学生已满足先决条件。仅当课程有先决条件 并且学生未满足 时,它才是一个值 returned,即未满足先决条件的课程编号。

注意:只有在您的示例数据中暗示每门课程只有一个先决条件时,这才有效。如果可以有一个或多个先决条件,您可能希望更改为数字 returns,其中 0 表示没有或全部满足先决条件,非零表示未满足先决条件的数量。