Oracle 使用条件创建触发器

Oracle 使用条件创建触发器,oracle,plsql,triggers,Oracle,Plsql,Triggers,我试图创建一个触发器,当学生在没有先决条件的情况下注册课程,但我失败时,该触发器将值学生id和课程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

我试图创建一个触发器,当学生在没有先决条件的情况下注册课程,但我失败时,该触发器将值
学生id
课程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-课程:具有课程id(PK)和课程名称

2-学生:有学生id(PK)和学生姓名

3个学生的课程:每个学生都有自己的课程

4-先修课程:每门课程都有先修课程

5-警报:当任何学生在没有先决条件的情况下注册课程时,触发存储学生id、课程id的警报

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

COURSE_NUMBER COURSE_PREREQUISITE 1 null 2 1 3 null 4 3 课程号课程先决条件 1空 2 1 3空 4 3
如果学生在没有先决条件的情况下注册课程,则查询先决条件的结果将为空。因此,如果课程有一个先决条件,而学生已经接受了先决条件,那么你希望结果是相同的。这使得后续的逻辑更加容易。因此,如果课程有一个学生没有参加的先决条件,结果将是该先决条件的课程id(您可以使用该id显示有意义的错误消息)

如果课程没有先决条件,则返回NULL的查询很容易:

select P.COURSE_PREREQUISITE Result
into   RequiredReq
from   Prerequisites P
where  P.COURSE_NUMBER = :new.course_id;
当然,如果有先决条件,它会返回先决条件的课程id,但我们稍后会处理这个问题。现在,我们想加入学生课程表:

join   STUDENTS_COURSES SC
    on SC.COURSE_NUMBER = P.COURSE_PREREQUISITE
   and SC.Student_ID    = :new.Student_ID
然而,这并不能提供我们所需要的一切。首先,如果学生没有接受先决条件,查询将不返回任何内容,因此我们将得到一个NO_DATA_FOUND错误。第二,如果学生已经取得了先决条件,它将返回课程id,但在这种情况下,我们希望它返回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;
这给了我们想要的一切,但不是以正确的方式。如果先决条件未满足,则返回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表示课程没有先决条件,或者学生满足先决条件。只有当课程有一个先决条件,而学生没有满足时,才会返回一个值,即未满足先决条件的课程编号


注意:只有在每个课程只有一个先决条件的情况下,如示例数据所示,这才有效。如果可以有一个或多个先决条件,您可能希望更改为数字返回,0表示没有或所有满足的先决条件,非零表示未满足的先决条件的数量。

那么,学生课程是否包含所有学生的历史?请显示完整的表架构。好的,但我现在无法放置架构,因为我没有足够的声誉。只需显示表定义。您现在可以阅读我问题中的表定义。谢谢。