为什么输出的只是最后一个值? Oracle 循环游标
Why is the output only the last value? Oracle loop cursor
我正在尝试输出教授教授的课程列表,方法是通过我的函数的参数接收教授的 ID,并显示所有课程,每门课程用逗号分隔。例如,如果教授教授人文、科学和数学,我希望输出为:'Humanities, Science, Math'。但是,我得到的只是 'Math,'。它只显示它找到的与教授的 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,但我不想使用它。
在你的循环中,你重新分配给 test
变量,而不是附加到它。这就是为什么在循环结束时,它只会保存 item.name
.
的最后一个值
赋值应该类似于
test := test || ',' || item.name
另请注意,这将在字符串的开头留下一个逗号。您可能想要 return ltrim(test, ',')
.
而不是 returning 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
我正在尝试输出教授教授的课程列表,方法是通过我的函数的参数接收教授的 ID,并显示所有课程,每门课程用逗号分隔。例如,如果教授教授人文、科学和数学,我希望输出为:'Humanities, Science, Math'。但是,我得到的只是 'Math,'。它只显示它找到的与教授的 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,但我不想使用它。
在你的循环中,你重新分配给 test
变量,而不是附加到它。这就是为什么在循环结束时,它只会保存 item.name
.
赋值应该类似于
test := test || ',' || item.name
另请注意,这将在字符串的开头留下一个逗号。您可能想要 return ltrim(test, ',')
.
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