2016-10-20 106 views
0

我想顯示的平均分數,但即使代碼被執行其沒有得到顯示,這裏是我的代碼:無法顯示平均

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 : 
+0

如果直接針對數據運行查詢,您會得到什麼結果? – FJT

+0

我得到的輸出: 73 –

回答

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. 如果您使用循環遊標,則不需要into子句 - 僅當您使用顯式選擇語句時才適用。你也不需要聲明你自己的變量來保存遊標返回的數據 - 遊標爲循環聲明瞭記錄變量來爲你返回行 - 在你的例子中,這將是c,爲了清楚起見,我已將其更名爲rec
  3. 給予標識符名稱以反映他們的/所做的事情對於易於維護,可讀性等也是必不可少的。
  4. 當從遊標引用字段的內容時,使用記錄變量,例如, rec.student_idrec.g_score。因此,重要的是給你的專欄別名,如果你做任何事情比直接選擇(例如,我已經給avg(grade.score)別名,但我不需要打擾grade.student_id
  5. 如果沒有記錄由遊標返回,你將永遠不會得到一個no_data_found異常。相反,您必須檢查是否有任何行返回 - 最簡單的方法是使用某種計數器。循環完成後,您可以檢查計數器。如果它顯示沒有行被返回,那麼你可以自己提出no_data_found錯誤 - 或者,更簡單地說,你可以跳過異常塊,只是把dbms_output語句放在那裏。因人而異。
  6. 如果您打算使用異常塊,那麼在生產代碼中,您可能會想要引發實際的錯誤。在這種情況下,您將使用RAISE,或者,如果您需要傳遞用戶定義的錯誤消息,則請使用RAISE_APPLICATION_ERROR
  7. 最後,我猜這是某種家庭作業問題,因此,dbms_output語句的存在是可以的。但是,在現實世界中,您只想使用dbms_output進行臨時調試或在非生產代碼中使用,因爲依靠dbms_output將信息傳遞給調用代碼只是要求麻煩。它不健壯,並且有更好,更可靠的方法來傳遞數據。