2012-11-22 52 views
1

我需要以管理员标识依赖于传递参数的所有员工的字符串格式返回员工姓名。当我编译函数时,我得到一个错误。下面是函数的代码:这块PLSQL如何编译?

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 remainder rem and or ||

任何人都可以帮助我吗?

回答

5

正如在其他的答案为什么你的功能将不能编译的原因说是一举三得。

  1. 您已声明变量v_names并将其引用为v_name
  2. PL/SQL中的赋值运算符为:=,您正在使用等号运算符=
  3. 你在你的return语句中缺少一个分号;它应该是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; 
/

请注意,我做了一些其他的变化:

  1. 前面加上不同的字母上比变量的函数参数,使之清楚哪个是哪个。
  2. 添加一些异常处理来处理没有该特定管理器的数据。
  3. 如果您没有数据返回NULL,您将返回,。如果你想返回一个逗号,而不是简单地把它放在异常中。
  4. 而不是费心创建一个游标,并通过它循环等我让甲骨文做繁重的工作。

很遗憾您希望返回一个逗号分隔的列表,因为之后您将无法在Oracle中使用逗号分隔列表。返回类似数组或包含所有姓氏的开放游标可能更为正常。我认为,在这个答案中,你有充分的理由去做你自己。

+0

+一个很好的解释。 – user75ponic

1

我猜你应该使用:=代替=

v_name := v_name || emp_rec.last_name ||', '; 

一件事,你还需要在return v_name末加上分号;return v_name;

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; 
/