PL / SQL编写更新列的过程?

时间:2017-10-17 07:29:30

标签: sql oracle plsql oracle10g

我应该根据程序将学生成绩更新为'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;
/   

6 个答案:

答案 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)

以下是您的代码中的问题:

  1. 此查询毫无意义:

    SELECT sID into p_id_enrolled 
      FROM Enrolling
      WHERE sID = p_sID
      AND classID = p_classID
    

    您选择sIDp_id_enrolled,但在WHERE子句中,您过滤了sID = p_sID,因此p_id_enrolled将始终等于p_sID,并且根本不需要这个选择语句。

  2. 此更新语句更新整个表:

    UPDATE Enrolling
       SET GRADE = 'A';
    

    您需要添加过滤子句才能仅更新一行。

  3. 如果学生未在课程中注册,则查询不会返回任何行,您将获得NO_DATA_FOUND例外。要处理它,您需要捕获异常或计算学生数量。

  4. 我建议使用以下内容:

    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更安全,因为当您尝试插入NULLSELECT 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;
/