Oracle 如何编译这段PLSQL?

Oracle 如何编译这段PLSQL?,oracle,function,plsql,Oracle,Function,Plsql,我需要以字符串格式返回经理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);

我需要以字符串格式返回经理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: 遇到符号;当预期出现以下情况之一时: ,*&-+/mod剩余rem和或||

有人能帮我吗?

我想你应该用:=代替= 像

还有一件事你还需要加上分号;在返回v_name like的末尾 返回v_名称

我想你应该用:=代替= 像

还有一件事你还需要加上分号;在返回v_name like的末尾
返回v_名称

有几件事需要注意

声明为v_名称但用作v_名称

Assignemnt应该像v_name:=v_name | | emp_rec.last_name|| ', ';

v_名称的声明大小为10,它太小,可能会 执行时给出一个错误,以便声明为

v_name employees.姓氏%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;
/

有几件事需要注意

声明为v_名称但用作v_名称

Assignemnt应该像v_name:=v_name | | emp_rec.last_name|| ', ';

v_名称的声明大小为10,它太小,可能会 执行时给出一个错误,以便声明为

v_name employees.姓氏%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;
/

如其他答案所述,函数无法编译的原因有三个

您已经声明了变量v_name,并将其引用为v_name。 PL/SQL中的赋值运算符为:=,您使用的是相等运算符=。 您的返回语句中缺少分号;它应该是返回v_name; 它不会停止函数的编译,但变量v_names被声明为varchar210。当一个经理有多个下属时,他们的姓氏不太可能与此相符。您可能应该以最大大小声明此变量;以防万一

我想补充一点,你这样做效率很低。如果在SQL中进行字符串聚合而不是PL/SQL循环,则效果会更好。从11g版本2开始,您就拥有了该功能;如果您使用的是之前的版本,那么有很多方法可以达到相同的效果

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来完成这项繁重的工作。
非常奇怪的是,您可能希望返回一个逗号分隔的列表,因为在Oracle中以后几乎无法使用它。返回数组或包含所有姓氏的打开游标之类的内容可能更为正常。在这个答案中,我假设你有一个很好的理由去做你想做的事情。

正如其他答案中所述,你的函数无法编译的原因有三个

您已经声明了变量v_name,并将其引用为v_name。 PL/SQL中的赋值运算符为:=,您使用的是相等运算符=。 您的返回语句中缺少分号;它应该是返回v_name; 它不会停止函数的编译,但变量v_names被声明为varchar210。当一个经理有多个下属时,他们的姓氏不太可能与此相符。您可能应该以最大大小声明此变量;以防万一

我想补充一点,你这样做效率很低。如果在SQL中进行字符串聚合而不是PL/SQL循环,则效果会更好。从11g版本2开始,您就拥有了该功能;如果您使用的是之前的版本,那么有很多方法可以达到相同的效果

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来完成这项繁重的工作。 非常奇怪的是,您可能希望返回一个逗号分隔的列表,因为在Oracle中以后几乎无法使用它。返回可能更正常 类似于包含所有姓氏的数组或打开的游标。在这个答案中,我假设你有一个很好的理由去做你自己