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

PL/SQL向if/else语句添加另一个条件,sql,oracle,plsql,oracle10g,Sql,Oracle,Plsql,Oracle10g,我需要检查学生是否已经在callnum课程号的等待名单上 如果学生已经在等待名单上,则不应将其添加到等待名单中 它应该打印一条信息,说明这一点,但我不太确定我会把它放在哪里 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 c

我需要检查学生是否已经在callnum课程号的等待名单上

如果学生已经在等待名单上,则不应将其添加到等待名单中

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

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.';

对于等待列表,可以使用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; 

你的修改不起作用。首先,select下面的elsif将不会编译,因为您缺少into子句。但即使有了它,它也会在执行过程中失败,没有发现异常数据。但是,甚至不需要选择。请查阅合并语句的文档。在这种情况下,通过最后一个端点删除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子句标识的行,则不会进一步处理,如果它没有找到,则将执行insert。再次了解Merge语句是如何工作的。“如果”可以是一个非常有力的陈述,但你必须清楚地理解它,它才能为你工作。

我想到了另外两个解决方案:

对代码的简单更新可以是:

 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;
您还可以在等待列表上创建唯一索引:

CREATE UNIQUE INDEX waitlist_u1 ON waitlist (wl_callnum);
然后捕获DUP_VAL_ON_索引异常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;

那么问题出在哪里呢?只要写一个select查询来检查等待名单上的学生…elsif语句在我编辑的帖子中有效吗?不-你不能说如果select。。。或者如果选择。。。因为SELECT语句不返回布尔值。谢谢!我可以把它放在else语句下面吗?