【问题标题】:Function in Oracle that returns 2 different columns of a tableOracle 中返回表的 2 个不同列的函数
【发布时间】:2019-07-05 01:27:16
【问题描述】:

我正在尝试创建一个在单个表中返回 2 个不同列的函数,有人可以帮我吗?

我已经尝试过这种方式:

CREATE FUNCTION return_id_grade(subjectId IN NUMBER, semesterYear IN DATE , n IN INT, option IN INT)
RETURN NUMBER
                IS studentId NUMBER(5),
                IS studentGrade NUMBER(2,1);
   BEGIN
                SELECT DISTINCT student_id INTO studentId,
                       grade INTO studentGrade
                    FROM (SELECT studentId, grade, dense_rank() over (ORDER BY grade desc) rank FROM old_students) 
                        WHERE subject_id = subjectId 
                            AND semester_year = semesterYear
                            AND rank = n
                            AND rownum <= 1
    CASE 
                WHEN option = 1 then RETURN(student_id)
                WHEN option = 2 then RETURN(grade)
    END;

END;

我希望输出大学班级的n'NTH成绩和学生ID,但实际只能输出参数字段上接收到的选项。

【问题讨论】:

  • 快速阅读:你不见了;在 SELECT INTO 语句之后。然后,带有 RETURN 语句的 CASE 表达式应该是相反的:RETURN CASE WHEN option = 1 then student_id WHEN option = 2 then grade END;
  • 你说得对,我错过了...谢谢...
  • 另外,您有两个 is 关键字。这是一个缩进大小。通常人们使用 2 或 4 个空格。

标签: oracle plsql oracle11g stored-functions


【解决方案1】:

a.您不能使用 Select colum1 INTO variable1 , colum2 INTO variable2 。它必须像: 选择 column1 , column2 INTO variable1 , variable 2

b.创建一个对象类型并将其用作过程中的输出参数

c.调用过程后有选项条件。

示例代码:

      CREATE OR REPLACE TYPE ty_obj_idgrade AS OBJECT
      (studentId    NUMBER(5)
      ,studentGrade    NUMBER(2,1)
       );



      CREATE OR REPLACE PROCEDURE return_id_grade(
                                        subjectId IN NUMBER, 
                                        semesterYear IN DATE , 
                                        n IN INT, 
                                       -- options IN INT
                                        ,p_idgrade OUT ty_obj_idgrade) IS
       BEGIN
            SELECT DISTINCT student_id --INTO studentId,
                            ,grade --INTO studentGrade
                       INTO p_idgrade.studentId
                            ,p_idgrade.grade
                       FROM (SELECT studentId
                                    ,grade
                                    ,dense_rank() over (ORDER BY grade desc) rank 
                                    ,subject_id
                                    ,semester_year
                               FROM old_students )
                WHERE  subject_id = subjectId
                  AND  semester_year = semesterYear
                  AND  rank = n
                  AND  rownum <= 1;

EXCEPTION
WHEN OTHERS THEN
    dbms_output.put_line('we are inside when others -->'||sqlerrm);

END;

调用你的程序。

由于 options 被用作 IN 参数,它应该在 prc/fnc 之外可用 所以这可以在 prc/fnc 调用之后完成 如果选项 = 1 然后 值:= p_idgrade.conatct 别的 值:= p_idgrade.grade 如果结束;

希望对你有帮助。

【讨论】:

  • 完全理解!!感谢您的回答。我想知道我不使用选项变量的其他方式,以及是否有其他方式可以在示例中输出以下结果:StudentId 和 StudentGrade。 , 002. 9,5.
【解决方案2】:

没有尝试编译它,但是这样的东西应该很接近。

CREATE FUNCTION return_id_grade(subjectId IN NUMBER, semesterYear IN DATE , n IN INT, option IN INT)
RETURN NUMBER IS
studentId NUMBER(5),
studentGrade NUMBER(2,1);
   BEGIN
                SELECT DISTINCT student_id, grade
                INTO studentId, studentGrade
                    FROM (SELECT studentId, grade, dense_rank() over (ORDER BY grade desc) rank FROM old_students) 
                        WHERE subject_id = subjectId 
                            AND semester_year = semesterYear
                            AND rank = n
                            AND rownum <= 1;
    IF option = 1 then 
         RETURN studentId ;
    ELSE
        RETURN studentGrade ;
    END IF;
    END;

END;

但是,这个功能真的不是一个好的设计。一个函数应该执行一个任务。如果您想返回这两项,请创建一个 PL/SQL 记录类型,并使用带有 OUT 参数的存储过程并在过程中返回。

【讨论】:

  • 感谢您的回答!但是有没有办法可以在示例中输出结果:StudentId 和 StudentGrade。 , 002. 9,5.而不是使用变量选项?
  • 不确定我是否理解“不使用变量”?如果您不将结果存储在某个地方,您希望如何引用它们?
  • 实际上,我正在考虑同时获得两个结果(StudentId 和 His Grade),而不是必须使用变量选项选择其中一个。
【解决方案3】:

您可以直接尝试在查询中使用OPTION,如下:

CREATE FUNCTION RETURN_ID_GRADE (
    SUBJECTID      IN             NUMBER,
    SEMESTERYEAR   IN             DATE,
    N              IN             INT,
    OPTION         IN             INT
) RETURN NUMBER IS
    LV_RETURN_NUMBER   NUMBER(6, 1);
BEGIN
    -- QUERY TO FETCH REQUIRED DATA ONLY
    SELECT -- DISTINCT -- DISTINCT IS NOT NEEDED AS ROWNUM <= 1 IS USED
        CASE
            WHEN OPTION = 1 THEN STUDENT_ID
            ELSE GRADE
        END AS LV_RETURN_NUMBER
    INTO LV_RETURN_NUMBER -- STORE VALUE BASED ON OPTION
    FROM
        (
            SELECT
                STUDENTID,
                GRADE,
                DENSE_RANK() OVER(
                    ORDER BY
                        GRADE DESC
                ) RANK
            FROM
                OLD_STUDENTS
        )
    WHERE
        SUBJECT_ID = SUBJECTID
        AND SEMESTER_YEAR = SEMESTERYEAR
        AND RANK = N
        AND ROWNUM <= 1;

    RETURN LV_RETURN_NUMBER; -- RETURN THE VARIABLE

END;

干杯!!

【讨论】:

  • 完美运行!!但是是否有任何其他选项而不是使用变量选项,我可以在示例中输出结果:StudentId 和 StudentGrade。 , 002. 9,5. Tnks 为 anwser!
猜你喜欢
  • 2013-10-22
  • 2017-07-22
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 1970-01-01
  • 1970-01-01
  • 2019-09-24
  • 2013-01-15
相关资源
最近更新 更多