我需要为经理ID取决于传递参数的所有员工返回字符串格式的员工姓名。当我编译该函数时,我得到一个错误。这是功能代码:
create or replace function Employee(v_manid IN employees.manager_id%type)
return varchar2
AS
cursor cur_emp is select last_name from employees where manager_id = v_manid;
v_names varchar2(10);
begin
for emp_rec in cur_emp
loop
v_name = v_name || emp_rec.last_name ||', ';
end loop;
return v_name
end;
/
错误是:
错误(8,8):PLS-00103:在期待一个符号时遇到符号“=” 以下内容:: =。 (@%;错误(8,44):PLS-00103: 遇到符号“;”当期待以下之一:) ,*& - + / at mod remaining rem和or ||
有人可以帮我吗?
答案 0 :(得分:5)
如其他答案中所述,您的函数无法编译的原因有三个。
v_names
并将其引用为v_name
。:=
,您使用的是等于运算符=
。return v_name;
它不会停止编译函数,但变量v_names
被声明为varchar2(10)
。当具有多个下属的经理所有姓氏都适合这种情况时,这种情况极不可能发生。您应该使用最大大小声明此变量;以防万一。
我想补充一点,你这样做的效率非常低。如果你要在SQL中进行字符串聚合而不是PL / SQL循环,那就更好了。从11g第2版开始,您拥有listagg()
功能;如果您之前使用的版本有足够的other string aggregation techniques来获得相同的结果。
create or replace function employee ( p_manid in employees.manager_id%type
) return varchar2 is
v_names varchar2(32767); -- Maximum size, just in case
begin
select listagg(lastname, ', ') within group ( order by lastname )
into v_names
from employees
where manager_id = p_manid;
return v_names;
exception when no_data_found then
return null;
end;
/
请注意我做的其他一些更改:
,
我返回NULL。如果你想返回一个逗号而不是简单地把它放在异常中。你想要返回一个以逗号分隔的列表,这很奇怪,因为在Oracle之后你几乎无法用它做什么。返回类似数组的内容或包含所有姓氏的开放游标可能更为正常。在这个答案中,我假设你有充分的理由去做你自己。
答案 1 :(得分:3)
有几点需要注意。
声明为v_names
但用作v_name
Assignemnt应该像v_name := v_name || emp_rec.last_name ||
', ';
v_name
声明大小为10,它会太小而且会
执行时出错,因此可以声明为
v_name employees.last_name%TYPE;
您可以将您的功能创建为
CREATE OR REPLACE FUNCTION employee (v_manid IN employees.manager_id%TYPE)
RETURN VARCHAR2
AS
v_name employees.last_name%TYPE;
CURSOR cur_emp
IS
SELECT last_name
FROM employees
WHERE manager_id = v_manid;
BEGIN
FOR emp_rec IN cur_emp
LOOP
v_name := v_name || emp_rec.last_name || ', ';
END LOOP;
RETURN v_name;
END;
/
答案 2 :(得分:1)
我猜您应该使用:=
代替=
像
v_name := v_name || emp_rec.last_name ||', ';
还需要在;
末尾添加分号return v_name
return v_name;