2017-04-27 8 views
0

studentIDを入力として受け入れる関数内でGPAを計算しようとしています。私の問題は、変数lv_gpa_calcがループがカーソルセットを介して機能するときに、それ自体に追加されていないということです。私はDBMS_OUTPUT.PUT_LINEを追加してカーソルが正しく設定されていることを確認し、lv_gpa_calcの正しい個々の行の値を画面に表示しますが、SQLブロックの関数で返されたときは追加されませんこれらの値はすべて一緒になります。 CURSOR FOR LOOP内で変数を自分自身に設定することはできませんか?PLループ用SQLカーソル:同じ変数に値を加算して合計を出力します

更新:lv_gpa_calcを初期化すると、変数値が自分自身に追加されていない問題が修正されました。

CREATE OR REPLACE 
FUNCTION CALCULATE_GPA 
(p_studentID IN number) 
RETURN NUMBER 
IS 
    CURSOR cur_gpa IS 
     SELECT grade, grade_value, credit_hours 
     FROM grade 
     JOIN enrollment USING (Grade) 
     JOIN section USING (term_code, subject_code, course_number, section) 
     JOIN course USING (subject_code, course_number) 
     WHERE student_ID = p_studentID; 

    lv_gpa_calc NUMBER(4,2):=0; 
BEGIN 
    FOR rec_gpa IN cur_gpa LOOP 
    lv_gpa_calc:= lv_gpa_calc + ((rec_gpa.grade_value * rec_gpa.credit_hours)/rec_gpa.credit_hours); 
    DBMS_OUTPUT.PUT_LINE(lv_gpa_calc); 
    END LOOP; 
    RETURN lv_gpa_calc; 

END CALCULATE_GPA; 

答えて

0

コードの問題は、変数lv_gpa_calcが初期化されていないことです。 NULLに何でも追加すると、NULLとなります。

簡素化された作業テストケース:

--DROP TABLE my_numbers; 

CREATE TABLE my_numbers (
    id NUMBER 
); 
/

BEGIN 
    FOR l_i IN 1..10 LOOP 
    INSERT INTO my_numbers VALUES (DBMS_RANDOM.RANDOM); 
    END LOOP; 
    COMMIT; 
END; 
/

SELECT * FROM my_numbers; 
/

DECLARE 
    CURSOR cur IS 
    SELECT id 
     FROM my_numbers; 

    l_sum NUMBER(10) := 0; 
BEGIN 
    FOR rec IN cur LOOP  
    l_sum := l_sum + rec.id;  
    DBMS_OUTPUT.PUT_LINE('l_sum = ' || l_sum); 
    END LOOP; 
    DBMS_OUTPUT.PUT_LINE('Sum = ' || l_sum); 
END; 
/

重要な行は次のようになります。

l_sum NUMBER(10) := 0; 

初期:=0がなければ、それは動作しません。

+0

入力いただきありがとうございます!感謝します。 BEGINセクションが0になる前に変数を初期化しなければならない理由や、それを動作させるための何らかの値を知っていますか? – arooney88

+1

初期化されていなければ、値はNULLです。次に、(sumのように2つのオペランドを持つ)ほとんどのバイナリ演算はNULL値を返します。 – kpater87

関連する問題