SQL过程 - 比较值

时间:2016-11-01 02:42:34

标签: sql oracle

我正在尝试创建一个过程,在完成一些检查后将信息添加到表中。其中一项检查需要比较另一个表中是否存在另一个表中的字段。我目前正在尝试找到一种方法来将单个字段与另一个表的整个列进行比较,以查看它们是否匹配 例如。单个字段为PrerequisiteID,我需要确保此ID存在于CourseID下的课程表中。我正在努力弄清楚如何将单prerequisiteIDcourseID的整个列进行比较。任何帮助将不胜感激。

我正在做的实际问题是:

  

编写程序 NEW_COURSE ,使用给定的课程详细信息以提供全新的课程。在开设新课程之前,该程序可确保:

     
      
  1. COURSE 表中已存在先决条件课程(如果有)。为简单起见,我们假装课程最多只能有一门课程作为先决条件。

  2.   
  3. 课程的先决条件必须是较低的水平。例如,ISYS326的先决条件必须是100或200级课程,不能是300级课程。

  4.         

    如果上述任一要求失败,则该过程会引发异常WRONG_PREREQ,该异常会打印相应的警报消息,并且不会修改 COURSE 表。

表格结构:

create table COURSE ( 
    COURSEID CHAR(8) not null, 
    DEPTID CHAR(8) not null, 
    COURSENAME VARCHAR2(20), 
    TEXTBOOK VARCHAR2(20), 
    CREDITHOUR NUMBER(2), 
    MAX_ENROL NUMBER(4), 
    ACTUAL_ENROL NUMBER(4), 
    AVAILABILITY NUMBER(4), 
    constraint PK_COURSE primary key (COURSEID) 
);

create table HAS_PREREQUISITE ( 
    COURSEID CHAR(8) not null, 
    PREREQUISITEID CHAR(8) not null, 
    constraint PK_HAS_PREREQUISITE primary key (COURSEID, PREREQUISITEID) 
); 

alter table HAS_PREREQUISITE 
add constraint FK_HAS_PRER_HAS_PRERE_COURSE foreign key (COURSEID)
references COURSE (COURSEID); 

alter table HAS_PREREQUISITE 
add constraint FK_HAS_PRER_HAS_PRERE_COURSE1 foreign key (PREREQUISITEID) 
references COURSE (COURSEID);

到目前为止,这是我的程序,我知道这是不正确的我只是想在那里得到一些东西:

CREATE OR REPLACE 
PROCEDURE NEW_COURSE
(
    c_course_ID      COURSE.COURSEID%type,
    c_dept_ID         COURSE.DEPTID%type,
    c_coursename    COURSE.COURSENAME%type,
    c_textbook         COURSE.TEXTBOOK%type,
    c_credithour       COURSE.CREDITHOUR%type,
    c_max_enrol       COURSE.MAX_ENROL%type,
    c_actual_enrol    COURSE.ACTUAL_ENROL%type,
    c_availability      COURSE.AVAILABILITY%type,
    p_prerequisite_ID  HAS_PREREQUISITE.PREREQUISITEID%type
)

IS

BEGIN

  IF (p_prerequisite_ID != COURSE.courseID) THEN WRONG_PREREQ (-20205, 'That prerequisite does not exist');
  ELSE IF( p_prerequisite_ID > c_course_ID) THEN WRONG_PREREQ(-20205, 'That is not a valid prerequisite');
  ELSE
  INSERT INTO COURSE (COURSEID, DEPTID, COURSENAME, TEXTBOOK, CREDITHOUR, MAX_ENROL, ACTUAL_ENROL, AVAILABILITY)
  VALUES (c_course_ID, c_dept_ID, c_coursename, c_textbook, c_credithour, c_max_enrol, c_actual_enrol, c_availability);
  END IF; 

END NEW_COURSE;

课程数据:

+----------+----------+------------+----------+------------+-----------+--------------+--------------+
| CourseID |  DeptID  | COURSENAME | TEXTBOOK | CREDITHOUR | MAX_ENROL | ACTUAL_ENROL | AVAILABILITY |
+----------+----------+------------+----------+------------+-----------+--------------+--------------+
| ISYS224  | FSE      |            |          |            |           |              |              |
| COMP225  | FSE      |            |          |            |           |              |              |
| ISYS114  | FSE      |            |          |            |           |              |              |
| COMP115  | FSE      |            |          |            |           |              |              |
+----------+----------+------------+----------+------------+-----------+--------------+--------------+

先决条件没有任何数据,但这里是它的表定义:

+----------------+--------------+
|  Column Name   |  Data Type   |
+----------------+--------------+
| COURSEID       | CHAR(8 BYTE) |
| PREREQUISITEID | CHAR(8 BYTE) |
+----------------+--------------+

1 个答案:

答案 0 :(得分:0)

所以我们这里有一个智能密钥,智能密钥是愚蠢的(因为它们很难验证,并且总是需要消费程序的额外代码)。 COURSEID ISYS224分为三个部分:

  • ISYS = subject
  • 2 =课程级别
  • 24 =班级编号(比如说)

如果您的数据模型是正确的(并且显然它是您的老师的错,那么它不是),解决方案会很简单,因为查询很明显。

实际上,您需要自己将COURSEID分解为其组成部分。让我们假设SUBJECT总是四个字符长,因为其他任何东西都是虐待狂。然后查询是:

select c.courseid
from course c 
where substr(c.courseid, 1, 4) = substr(p_prerequisite_id, 1, 4)
and substr(c.courseid, 5, 1) < substr(p_prerequisite_id, 5, 1)
;

如果先决条件不符合规则,这将抛出NO_DATA_FOUND。使用例外部分来处理这个问题。

或者,您可以将先决条件课程记录选择到局部变量中,并在PL / SQL代码中进行切割。

select c.courseid into l_prerequisite_course
from course c 
where c.courseid = p_prerequisite_id;

if substr(l_prerequisite_course, 1, 4) = substr(p_prerequisite_id, 1, 4)
or substr(l_prerequisite_course, 5, 1) < substr(p_prerequisite_id, 5, 1)
then raise ...
;