我需要检查一个学生是否已经在等待呼叫列表(类号)。
如果学生已经在候补名单上,则不应将他或她添加到候补名单中。
它应该打印一条消息,说明但我不太确定我会把它放在哪里。
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.';
答案 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)
我还有其他两个解决方案:
您的代码的简单更新可能是:
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_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;