【问题标题】:How to transfer cursor to a procedure?如何将光标转移到程序?
【发布时间】:2016-12-08 00:33:05
【问题描述】:
DECLARE
    CURSOR cursor1 IS SELECT STUDENTNAME, COURSEID, COURSEDESCRIPTION, COURSECREDITS, GRADE
    FROM STUDENTINFO
    WHERE STUDENTNAME = '&student'
    GROUP BY (STUDENTNAME, COURSEID, COURSEDESCRIPTION, COURSECREDITS, GRADE)
    ORDER BY COURSEID;
    S_NAME STUDENTINFO.STUDENTNAME%TYPE;
    S_COURSEID STUDENTINFO.COURSEID%TYPE;
    S_COURSEDESCRIPTION STUDENTINFO.COURSEDESCRIPTION%TYPE;
    S_COURSECREDITS STUDENTINFO.COURSECREDITS%TYPE;
    S_GRADE STUDENTINFO.GRADE%TYPE;
    S_TOTALCREDITS STUDENTINFO.COURSECREDITS%TYPE := 0;
    S_A STUDENTINFO.COURSECREDITS%TYPE := 4;
    S_B STUDENTINFO.COURSECREDITS%TYPE := 3;
    S_C STUDENTINFO.COURSECREDITS%TYPE := 2;
    S_D STUDENTINFO.COURSECREDITS%TYPE := 1;
    S_F STUDENTINFO.COURSECREDITS%TYPE := 0;
    S_GPABEFOREDIV STUDENTINFO.COURSECREDITS%TYPE := 0;
    S_CREDITSTOGPA STUDENTINFO.COURSECREDITS%TYPE := 0;
    S_GPA NUMBER(4,2);
BEGIN
    OPEN CURSOR1;
    LOOP 
    FETCH CURSOR1 INTO S_NAME, S_COURSEID, S_COURSEDESCRIPTION, S_COURSECREDITS, S_GRADE;
    EXIT WHEN cursor1%NOTFOUND;
        IF (S_GRADE = 'A') THEN
        S_CREDITSTOGPA := (S_COURSECREDITS * S_A);
        S_GPABEFOREDIV := S_GPABEFOREDIV + S_CREDITSTOGPA;
    ELSIF (S_GRADE = 'B') THEN
        S_CREDITSTOGPA := (S_COURSECREDITS * S_B);
        S_GPABEFOREDIV := S_GPABEFOREDIV + S_CREDITSTOGPA;
    ELSIF (S_GRADE = 'C') THEN
        S_CREDITSTOGPA := (S_COURSECREDITS * S_C);
        S_GPABEFOREDIV := S_GPABEFOREDIV + S_CREDITSTOGPA;
    ELSIF (S_GRADE = 'D') THEN
        S_CREDITSTOGPA := (S_COURSECREDITS * S_D);
        S_GPABEFOREDIV := S_GPABEFOREDIV + S_CREDITSTOGPA;
    ELSE
        S_CREDITSTOGPA := (S_COURSECREDITS * S_F);
        S_GPABEFOREDIV := S_GPABEFOREDIV + S_CREDITSTOGPA;
    END IF;
    DBMS_OUTPUT.PUT_LINE(CHR(10));
    DBMS_OUTPUT.PUT_LINE(S_COURSEID ||' '|| S_COURSEDESCRIPTION ||' '|| S_COURSECREDITS ||' '|| S_GRADE);
    S_TOTALCREDITS := S_TOTALCREDITS + S_COURSECREDITS;
    S_GPA := (S_GPABEFOREDIV / S_TOTALCREDITS);
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('Total Credits: ' || S_TOTALCREDITS);
    DBMS_OUTPUT.PUT_LINE('Overall GPA: ' || S_GPA);
    CLOSE CURSOR1;
END;
/

这是我在收到输入后输出学生 GPA 的光标。我需要将它转移到一个带有 1 in 参数(学生姓名)和 1 out(gpa)的过程。我完全迷失了从哪里开始。我假设我必须在某处使用循环才能将每门课程的学分相加,对吧?

【问题讨论】:

  • transfer the cursor 是什么意思?你想把上面的转换成一个过程吗?

标签: sql oracle plsql


【解决方案1】:

我假设您想将上述代码编写为一个以 student_name 作为输入并生成 gpa 作为输出的过程。这里:

CREATE OR REPLACE PROCEDURE GPA_PR(p_student_name in varchar2, p_gpa out number) is
    CURSOR cursor1 IS SELECT STUDENTNAME, COURSEID, COURSEDESCRIPTION, COURSECREDITS, GRADE
    FROM STUDENTINFO
    WHERE STUDENTNAME = p_student_name
    GROUP BY (STUDENTNAME, COURSEID, COURSEDESCRIPTION, COURSECREDITS, GRADE)
    ORDER BY COURSEID;
    S_NAME STUDENTINFO.STUDENTNAME%TYPE;
    S_COURSEID STUDENTINFO.COURSEID%TYPE;
    S_COURSEDESCRIPTION STUDENTINFO.COURSEDESCRIPTION%TYPE;
    S_COURSECREDITS STUDENTINFO.COURSECREDITS%TYPE;
    S_GRADE STUDENTINFO.GRADE%TYPE;
    S_TOTALCREDITS STUDENTINFO.COURSECREDITS%TYPE := 0;
    S_A STUDENTINFO.COURSECREDITS%TYPE := 4;
    S_B STUDENTINFO.COURSECREDITS%TYPE := 3;
    S_C STUDENTINFO.COURSECREDITS%TYPE := 2;
    S_D STUDENTINFO.COURSECREDITS%TYPE := 1;
    S_F STUDENTINFO.COURSECREDITS%TYPE := 0;
    S_GPABEFOREDIV STUDENTINFO.COURSECREDITS%TYPE := 0;
    S_CREDITSTOGPA STUDENTINFO.COURSECREDITS%TYPE := 0;
    S_GPA NUMBER(4,2);
BEGIN
    OPEN CURSOR1;
    LOOP 
    FETCH CURSOR1 INTO S_NAME, S_COURSEID, S_COURSEDESCRIPTION, S_COURSECREDITS, S_GRADE;
    EXIT WHEN cursor1%NOTFOUND;
    IF (S_GRADE = 'A') THEN
        S_CREDITSTOGPA := (S_COURSECREDITS * S_A);
        S_GPABEFOREDIV := S_GPABEFOREDIV + S_CREDITSTOGPA;
    ELSIF (S_GRADE = 'B') THEN
        S_CREDITSTOGPA := (S_COURSECREDITS * S_B);
        S_GPABEFOREDIV := S_GPABEFOREDIV + S_CREDITSTOGPA;
    ELSIF (S_GRADE = 'C') THEN
        S_CREDITSTOGPA := (S_COURSECREDITS * S_C);
        S_GPABEFOREDIV := S_GPABEFOREDIV + S_CREDITSTOGPA;
    ELSIF (S_GRADE = 'D') THEN
        S_CREDITSTOGPA := (S_COURSECREDITS * S_D);
        S_GPABEFOREDIV := S_GPABEFOREDIV + S_CREDITSTOGPA;
    ELSE
        S_CREDITSTOGPA := (S_COURSECREDITS * S_F);
        S_GPABEFOREDIV := S_GPABEFOREDIV + S_CREDITSTOGPA;
    END IF;
    DBMS_OUTPUT.PUT_LINE(CHR(10));
    DBMS_OUTPUT.PUT_LINE(S_COURSEID ||' '|| S_COURSEDESCRIPTION ||' '|| S_COURSECREDITS ||' '|| S_GRADE);
    S_TOTALCREDITS := S_TOTALCREDITS + S_COURSECREDITS;
    S_GPA := (S_GPABEFOREDIV / S_TOTALCREDITS);
    END LOOP;
    CLOSE CURSOR1;
    p_gpa := S_GPA;
END;
/

【讨论】:

  • 非常感谢!我没有意识到您可以将光标放入程序中。我想我必须重新编码整个事情。
【解决方案2】:

你可以在过程中返回带out参数的游标。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-19
    • 1970-01-01
    • 2016-01-06
    相关资源
    最近更新 更多