PL/SQL是否编写更新列的过程?
我应该根据程序将学生成绩更新为“a”PL/SQL是否编写更新列的过程?,sql,oracle,plsql,oracle10g,Sql,Oracle,Plsql,Oracle10g,我应该根据程序将学生成绩更新为“a” ChangeGrade(p_sID, p_classID) 如果该学生未注册该课程(p_classID),则会打印一条错误消息 这是表格: 注册 sID classID Grade *** ******* ***** 104 10440 B 102 10220 C ... ..... . 我应该做一个内部连接吗?以下是我所拥有的: Create or Replace ChangeG
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;
/
我不知道打印出来的是什么样的错误,但似乎您缺少了“;”在某些命令的末尾(在if语句中和select into之后)。正如我在评论中提到的,您的过程中有几个地方缺少分号(行termiator)。试试这个:
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;
/
你需要处理学生不在课堂上这一事实作为例外:
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;
/
我还为等级添加了一个参数,因为通过它也是合乎逻辑的。以下是代码中的问题:
SELECT sID into p_id_enrolled
FROM Enrolling
WHERE sID = p_sID
AND classID = p_classID
您将sID
选择到p\u id\u registered
中,但在WHERE
子句中您过滤sID=p\u sID
,因此p\u id\u registered
将始终等于p\u sID
,并且您根本不需要此select语句UPDATE Enrolling
SET GRADE = 'A';
您需要添加筛选子句以仅更新一行no\u DATA\u 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;
/
您还可以使用光标,然后查看该学生是否已注册该课程。如果他/她是,则更新成绩。我认为光标比
选择X进入n
更安全,因为当您尝试插入NULL
,选择NULL进入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;
/
那么错误是什么呢。你面临什么问题<代码>dbms\u输出。put\u行(“学生成绩已更改”)结尾缺少分号。应该是
dbms\u output.put\u行('学生成绩已更改')代码>在第7行获取错误:如果p_sID=p_id_已注册,则表示SQL命令未正确结束。在第2行,在p_id_中选择sID,它表示SQL语句被忽略。PL/SQL代码中的每个语句后面都必须跟有代码>在第7行获取错误:如果p_sID=p_id_已注册,则表示SQL命令未正确结束。在第2行,在p_id_登记中选择sID,它表示SQL语句已被忽略。这里不需要executeimmediate
。您可以说“您根本不需要这个SELECT语句”和“您将获得no\u DATA\u FOUND
异常”然后包括一条SQL语句,如果不解释为什么不遵循自己的建议,则不包括异常。@MT0谢谢,更正。事实上,错过关键字的不是我,我只是从问题中复制了代码;)另外,在第一个过程参数后缺少一个逗号。我认为答案并不完全正确。当学生未注册上课时,此代码SELECT count(*)into cnt
给出了一个丑陋的错误,ORA-01722:无效数字
。您将永远不会得到“学生记录不存在”select查询的输出将抛出一个NO\u DATA\u FOUND
异常。@MT0的问题不是处理异常,而是Op为什么出错。像往常一样,你试着超越OP的要求去思考,我对你无话可说。谢谢你的否决票。下面是一个示例“如果学生未注册课程(p_classID),则会打印错误消息。”是问题的一部分-您的过程不会这样做。(您缺少了过程
关键字)。这是最简单的解决方案,但稍微解释一下OP的代码为什么不起作用就好了。@MT0。如果此处也缺少异常块。请使用您的下一票特权。@XING此解决方案是正确的,没有异常处理块,因为它执行更新并检查更新是否更新了一行(通过匹配主键)或更新了零行(当找不到学生时)-由于未使用SELECT
语句,这两种可能性都不会引发NO\u DATA\u FOUND
异常。
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;
/