PL / SQL向if / else语句添加另一个条件

时间:2017-12-10 22:36:59

标签: sql oracle plsql oracle10g

我需要检查一个学生是否已经在等待呼叫列表(类号)。

如果学生已经在候补名单上,则不应将他或她添加到候补名单中。

它应该打印一条消息,说明但我不太确定我会把它放在哪里。

if p_ErrorMsg is null then -- Stores the error messages in p_ErrorMsg

  select capacity into v_capacity -- Checks the capacity limit. 
  from schclasses
  where callnum = p_callnum;

  select count(callnum) into v_enrolled
  from enrollments
  where callnum = p_callnum
  and grade is null;

  if v_capacity > v_enrolled then

    insert into enrollments values (p_snum, p_callnum, null); 
    commit;
    p_ErrorMsg := null;
    dbms_output.put_line('Student ' ||p_snum|| ' has been enrolled in class ' ||p_callnum|| '.'); -- Confirmation message that student is enrolled in course. 

  else

    insert into waitlist values (p_snum, p_callnum, to_char(sysdate)); -- Enrolls student to waitlist
    commit;
    p_ErrorMsg := 'Sorry, this class is full.';

     end if;
    end if;
  else
    p_ErrorMsg := 'Invalid student number.';
  end if;
end;

这会有用吗?

if v_capacity > v_enrolled then
    -- 11. If p_ErrorMsg is null (no error), then the student is enrolled.
    insert into enrollments values (p_snum, p_callnum, null);
    commit;
    p_ErrorMsg := null;
    dbms_output.put_line('Student ' ||p_snum|| ' has been enrolled in class ' ||p_callnum|| '.'); 

elsif select wl_snum, wl_callnum FROM waitlist wl
    if p_snum = wl_snum AND p_callnum = wl_callnum then
    p_ErrorMsg := 'Student is already on the waiting list for this CallNum';

else
    insert into waitlist values (p_snum, p_callnum, to_char(sysdate, 'DD/MM/YYYY HH24:MI:SS')); 
    commit;
    p_ErrorMsg := 'Class chosen is full. Student will be placed on the waiting list.';

3 个答案:

答案 0 :(得分:1)

您的修订不起作用。首先关闭选择下面的“elsif”将不会编译,因为你缺少“into子句。但即使有了它,它将在执行期间失败”没有找到数据“例外。但是选择甚至不是必需的。请查找Merge语句的文档。在这种情况下,通过最后的“end if”然后

删除“elsif”
else 
    *Place Merge here*
    if sql%rowcount = 0 
    then 
        p_ErrorMsg := 'Student is already on the waiting list for this CallNum';
    else 
        p_ErrorMsg := 'Class chosen is full. Student placed on the waiting list.';
end if; 

end-if ;  --( depending on having been deleted "above" )

在这种情况下,Merge语句将执行select,如果它发现行(由ON子句标识)将不会进一步处理,如果它没有找到,那么它将执行插入。再次了解Merge语句的工作原理。如果可以是一个非常强大的陈述,但你必须清楚地理解它,因为它适合你。

答案 1 :(得分:0)

对于等待列表,您可以使用Merge语句:

  merge into waitlist wl
    using (select p_snum student_id
                , p_callnum class_name
                , to_char(sysdate) wait_date
             from dual ) vals
       on (    vals.student_id = wl.student_id 
           and vals.class      = wl.class_name )
     when not Matched then
       insert (student_id, class_name, stupid_way_to_store_date))   -- <<< Actual Column Names >>> 
       values (vals.student_id, vals.class_name, vals.wait_date);

   if sql%rowcount = 0 then
      p_ErrorMsg := 'Sorry, this class is full.';
   end-if; 

答案 2 :(得分:0)

我还有其他两个解决方案:

  1. 您的代码的简单更新可能是:

     IF p_errormsg IS NULL THEN -- Stores the error messages in p_ErrorMsg
    
        SELECT capacity 
          INTO v_capacity -- Checks the capacity limit. 
          FROM schclasses
         WHERE callnum = p_callnum;
    
        SELECT count(callnum) 
          INTO v_enrolled
          FROM enrollments
         WHERE callnum = p_callnum
           AND grade IS NULL;
    
        IF v_capacity > v_enrolled THEN
    
            INSERT INTO enrollments 
                 VALUES (p_snum,
                         p_callnum,
                         null); 
            COMMIT;
    
            p_errormsg := null;
    
            DBMS_OUTPUT.PUT_LINE('Student ' || p_snum || ' has been enrolled in class ' || p_callnum || '.'); -- Confirmation message that student is enrolled in course. 
    
        ELSE
            SELECT COUNT(*)
              INTO ln_exists_in_waiting_list 
              FROM waitlist wl
             WHERE p_callnum = wl_callnum;
    
            IF ln_exists_in_waiting_list > 0 THEN
                INSERT INTO waitlist
                     VALUES (p_snum,
                             p_callnum,
                             to_char(SYSDATE)); -- Enrolls student to waitlist
                COMMIT;
                p_errormsg := 'Sorry, this class is full.';
            ELSE
                p_ErrorMsg := 'Student is already on the waiting list for this CallNum';
            END IF;
        ELSE
            p_errormsg := 'Invalid student number.';
        END IF;
    END IF;
    
  2. 您还可以在等候名单上创建唯一索引:

    CREATE UNIQUE INDEX waitlist_u1 ON waitlist (wl_callnum);
    
  3. 然后捕获DUP_VAL_ON_INDEX异常(ORA-00001:违反了唯一约束):

       IF p_errormsg IS NULL THEN -- Stores the error messages in p_ErrorMsg
    
            SELECT capacity 
              INTO v_capacity -- Checks the capacity limit. 
              FROM schclasses
             WHERE callnum = p_callnum;
    
            SELECT count(callnum) 
              INTO v_enrolled
              FROM enrollments
             WHERE callnum = p_callnum
               AND grade IS NULL;
    
            IF v_capacity > v_enrolled THEN
    
                INSERT INTO enrollments 
                     VALUES (p_snum,
                             p_callnum,
                             null); 
                COMMIT;
    
                p_errormsg := null;
    
                DBMS_OUTPUT.PUT_LINE('Student ' || p_snum || ' has been enrolled in class ' || p_callnum || '.'); -- Confirmation message that student is enrolled in course. 
    
            ELSE
                BEGIN
                    INSERT INTO waitlist
                         VALUES (p_snum,
                                 p_callnum,
                                 to_char(SYSDATE)); -- Enrolls student to waitlist
                    COMMIT;
                    p_errormsg := 'Sorry, this class is full.';
                EXCEPTION
                    WHEN DUP_VAL_ON_INDEX THEN
                        p_ErrorMsg := 'Student is already on the waiting list for this CallNum';
                END;
            END IF;
        ELSE
            p_errormsg := 'Invalid student number.';
        END IF;