无法显示平均值

时间:2016-10-20 14:11:41

标签: plsql

我想显示平均分数,但即使代码执行也没有显示,这是我的代码:

set serveroutput on size 10000;
declare
 s_student_id grade.student_id%type;
 g_score grade.score%type;
begin
 for c in (select distinct grade.student_id, avg(grade.score) into s_student_id, g_score from grade inner join class on grade.class_id = class.class_id group by grade.student_id having count(class.course_id) > 4)
 loop

    dbms_output.put_line('Student' || c.student_id || ' :' || g_score);

 end loop;
 exception
     when no_data_found then dbms_output.put_line('There are no students who selected more than 4 courses');
end;

/

输出:

anonymous block completed
Student1 :

1 个答案:

答案 0 :(得分:2)

我认为这就是你所追求的:

set serveroutput on size 10000;

declare
  v_counter integer := 0;
begin
  for rec in (select   grade.student_id,
                       avg(grade.score) g_score
              from     grade 
                       inner join class on grade.class_id = class.class_id
              group by grade.student_id
              having   count(class.course_id) > 4)
  loop
    v_counter := v_counter + 1;

    dbms_output.put_line('Student: ' || rec.student_id || ', avg score: ' || rec.g_score);

  end loop;

  if v_counter = 0 then
    raise no_data_found;
  end if;
exception
  when no_data_found then
    dbms_output.put_line('There are no students who selected more than 4 courses');
end;
/

有几点需要注意:

  1. 在理解,调试和维护代码时,良好的sql语句格式(和pl / sql)将对您有所帮助。如果你能轻松阅读,你很快就能理解它。
  2. 如果您正在使用游标for循环,则不需要into子句 - 这仅适用于使用显式select语句的情况。您也不需要声明自己的变量来保存游标返回的数据 - cursor-for-loop声明记录变量以便为您返回行 - 在您的示例中,这将是c ,为了清楚起见,我已将其重命名为rec
  3. 提供反映他们所做/做的标识符名称对于易于维护,可读性等也是必不可少的。
  4. 当从光标引用字段的内容时,使用记录变量,例如, rec.student_idrec.g_score。因此,如果你做的是直接选择以外的任何事情(例如我给了avg(grade.score)一个别名,那么给你的列别名是很重要的,但我不需要为grade.student_id而烦恼)
  5. 如果光标没有返回记录,则永远不会得到no_data_found异常。相反,你必须检查是否有任何行返回 - 最简单的方法是使用某种计数器。循环完成后,您可以检查计数器。如果它显示没有返回任何行,则可以自己引发no_data_found错误 - 或者更简单地说,您可以跳过异常块并将dbms_output语句放在那里。 YMMV。
  6. 如果您要使用异常块,在生产代码中,您很可能想要提出实际错误。在这种情况下,您可以使用RAISE,或者,如果您需要传递用户定义的错误消息,请RAISE_APPLICATION_ERROR
  7. 最后,我猜这是某种功课问题,因此,dbms_output语句的存在是可以的。但是,在现实世界中,您只想使用dbms_output进行临时调试或非生产代码,因为依靠dbms_output将信息传递给调用代码只是在寻找麻烦。它并不健壮,并且有更好,更可靠的传递数据的方法。