0

我正在尝试输出教授教授的课程列表,方法是通过我的函数的参数接收教授的 id,并显示所有课程,每个课程用逗号分隔。例如,如果教授教授人文、科学和数学,我希望输出为:“人文、科学、数学”。但是,我得到的只是“数学”。它只显示它找到的与教授的 id 匹配的最后一个字段。

CREATE OR REPLACE FUNCTION listar_cursos(prof NUMBER) RETURN VARCHAR
IS
    CURSOR C1 IS
        SELECT subject.name AS name FROM subject
               INNER JOIN course_semester 
               ON subject.id = course_semester.id_subject
        WHERE  course_semester.id_profesor = prof
        ORDER BY subject.name;

    test VARCHAR(500);
BEGIN
    FOR item IN C1
    LOOP
        test:= item.name ||',';
    END LOOP;

    RETURN test;
END;
/

我知道 listagg 存在,但我不想使用它。

4

1 回答 1

1

在您的循环中,您重新分配给test变量,而不是附加到它。这就是为什么在循环结束时,它只会保存item.name.

分配应该改为

test := test || ',' || item.name

另请注意,这将在字符串的开头留下一个逗号。test您可能想要返回,而不是返回ltrim(test, ',')

请注意,您不需要显式声明游标。使用隐式光标,代码更容易阅读(在我看来),如下所示。我创建示例表和数据来测试函数,然后展示函数代码及其使用方式。

create table subject as
  select 1 id, 'Humanities' name from dual union all
  select 2   , 'Science'         from dual union all
  select 3   , 'Math'            from dual
;

create table course_semester as
  select 1 id_subject, 201801 semester, 1002 as id_profesor from dual union all
  select 2           , 201702         , 1002 as id_profesor from dual union all
  select 3           , 201801         , 1002 as id_profesor from dual
;

CREATE OR REPLACE FUNCTION listar_cursos(prof NUMBER)  RETURN VARCHAR IS
 test VARCHAR(500);
BEGIN
FOR item IN 
(
  SELECT subject.name AS name FROM subject
      INNER JOIN course_semester 
  ON subject.id = course_semester.id_subject
  WHERE course_semester.id_profesor = prof
  ORDER BY subject.name
)
LOOP
  test:= test || ',' || item.name;
END LOOP;
RETURN ltrim(test, ',');
END;
/

select listar_cursos(1002) from dual;

LISTAR_CURSOS(1002)
-----------------------
Humanities,Math,Science
于 2018-08-31T00:08:00.523 回答