我应该根据程序将学生成绩更新为'A'
ChangeGrade(p_sID, p_classID)
如果学生未注册课程(p_classID),则会打印错误消息。
这是表格:
招生
sID classID Grade
*** ******* *****
104 10440 B
102 10220 C
... ..... .
我是否应该进行内部联接?这就是我所拥有的:
Create or Replace ChangeGrade (
p_sID enrolling.sID%type
p_classID enrolling.classID%type )
AS
p_id_enrolled NUMBER;
BEGIN
SELECT sID into p_id_enrolled
FROM Enrolling
WHERE sID = p_sID
AND classID = p_classID
IF p_sID = p_id_enrolled THEN
update Enrolling
set GRADE = 'A'
dbms_output.put_line('Student grade has been changed.')
ELSE
dbms_output.put_line('Student record does not exist.')
END IF;
END;
/
答案 0 :(得分:5)
Create or Replace procedure ChangeGrade (
p_sID enrolling.sID%type
p_classID enrolling.classID%type )
AS
BEGIN
update Enrolling
set GRADE = 'A'
where sID = p_sID
AND classID = p_classID;
IF SQL%ROWCOUNT > 0 THEN
dbms_output.put_line('Student grade has been changed.');
ELSE
dbms_output.put_line('Student record does not exist.');
END IF;
END;
答案 1 :(得分:2)
您需要处理学生不在课堂上作为例外的事实:
Create or Replace PROCEDURE ChangeGrade (
p_sID enrolling.sID%type,
p_classID enrolling.classID%type,
p_grade enrolling.grade%type )
AS
l_enrolled NUMBER;
BEGIN
SELECT sID INTO l_enrolled
FROM Enrolling
WHERE sID = p_sID
AND classID = p_classID;
IF l_enrolled = p_sID THEN
update Enrolling set GRADE = p_grade WHERE sID = p_sID and classID = p_classID;
dbms_output.put_line('Student grade has been changed.');
END IF;
EXCEPTION WHEN NO_DATA_FOUND
dbms_output.put_line('Student record does not exist for this class');
END;
/
我还为成绩添加了一个参数,因为它也是合理的。
答案 2 :(得分:1)
以下是您的代码中的问题:
此查询毫无意义:
SELECT sID into p_id_enrolled
FROM Enrolling
WHERE sID = p_sID
AND classID = p_classID
您选择sID
到p_id_enrolled
,但在WHERE
子句中,您过滤了sID = p_sID
,因此p_id_enrolled
将始终等于p_sID
,并且根本不需要这个选择语句。
此更新语句更新整个表:
UPDATE Enrolling
SET GRADE = 'A';
您需要添加过滤子句才能仅更新一行。
如果学生未在课程中注册,则查询不会返回任何行,您将获得NO_DATA_FOUND
例外。要处理它,您需要捕获异常或计算学生数量。
我建议使用以下内容:
Create or Replace procedure ChangeGrade (
p_sID enrolling.sID%type,
p_classID enrolling.classID%type )
AS
cnt NUMBER;
BEGIN
SELECT count(*) into cnt
FROM Enrolling
WHERE sID = p_sID
AND classID = p_classID;
IF cnt = 1 THEN
update Enrolling
set GRADE = 'A'
where sID = p_sID
AND classID = p_classID;
dbms_output.put_line('Student grade has been changed.');
ELSE
dbms_output.put_line('Student record does not exist.');
END IF;
END;
/
答案 3 :(得分:0)
我不知道打印出了什么样的错误,但似乎你错过了';'在一些命令的最后(在if语句和select into之后)。
答案 4 :(得分:0)
正如我的评论中提到的,您的程序中有几个地方缺少semicolon
(线路终结者)。试试这个:
CREATE OR REPLACE Procedure ChangeGrade (
p_sID enrolling.sID%type
p_classID enrolling.classID%type )
AS
p_id_enrolled NUMBER;
BEGIN
SELECT sID
INTO p_id_enrolled
FROM Enrolling
WHERE sID = p_sID AND classID = p_classID;
IF p_sID = p_id_enrolled
THEN
UPDATE Enrolling
SET GRADE = 'A'
WHERE sID = p_sID;
DBMS_OUTPUT.put_line ('Student grade has been changed.');
ELSE
DBMS_OUTPUT.put_line ('Student record does not exist.');
END IF;
EXCEPTION
WHEN NO_DATA_FOUND Then
dbms_output.put_line('Student record does not exist for this class');
END;
/
答案 5 :(得分:0)
您也可以使用光标,然后查看该学生是否已注册该课程。如果他/她是,那么更新成绩。我认为光标比SELECT X INTO n
更安全,因为当您尝试插入NULL
,SELECT NULL INTO n
时会出现一个丑陋的错误,而且这些错误通常很难找到。<登记/>
例如:
CREATE OR REPLACE ChangeGrade (p_sID enrolling.sID%TYPE,
p_classID enrolling.classID%TYPE)
AS
CURSOR cEnrolling IS
SELECT *
FROM Enrolling
WHERE SID = p_sID
AND classID = p_classID;
rEnrolling cEnrolling%ROWTYPE;
BEGIN
OPEN cEnrolling;
FETCH cEnrolling INTO rEnrolling;
IF cEnrolling%FOUND THEN
-- Student record found.
UPDATE Enrolling
SET Grade = 'A'
WHERE SID = rEnrolling.sId;
DBMS_OUTPUT.PUT_LINE('Student grade has been changed.');
ELSE
-- Student record not found.
DBMS_OUTPUT.PUT_LINE('Student record does not exist.');
END IF;
CLOSE cEnrolling;
END;
/