Sql PLS-00222:没有名称为'的函数;信息类型';存在于该范围内

Sql PLS-00222:没有名称为'的函数;信息类型';存在于该范围内,sql,oracle,plsql,Sql,Oracle,Plsql,我尝试在两种情况下返回记录表: 使用函数 使用匿名块 当我使用该函数时,一切正常,但当我试图将其转换为匿名块时,我收到上述错误。 代码如下: 对于功能: create or replace function get_info(p_city varchar2) return info_type_table as l_info info_type_table := info_type_table(); begin for i in (select e.employeeid,

我尝试在两种情况下返回记录表:

  • 使用函数
  • 使用匿名块
  • 当我使用该函数时,一切正常,但当我试图将其转换为匿名块时,我收到上述错误。 代码如下:

    对于功能:

    create or replace 
    function get_info(p_city varchar2) return info_type_table
    as
    l_info info_type_table := info_type_table();
    begin
        for i in (select  e.employeeid, 
                          e.lastname, 
                          c.customerid,
                          c.companyname,
                          o.orderid,
                          o.orderdate
                  from  ntw_employees e
                    inner join 
                        ntw_orders    o
                        on e.employeeid = o.employeeid
                    inner join 
                        ntw_customers c
                        on o.customerid = c.customerid
                  where e.city  = p_city)
        loop
            l_info.extend;
            l_info(l_info.count)  :=  (info_type(i.employeeid, i.lastname, i.customerid, i.companyname, i.orderid, i.orderdate));
        end loop;
        return l_info;
    end;
    
    以下是匿名块的示例:

    declare
    type info_type is record 
    (
        emp_no    number(3),
        lastname  varchar2(26),
        cust_no   varchar2(5),
        CO_name   varchar2(50),
        orderid   number(5),
        orderdate date
    );
    
    type info_type_table is table of info_type;
    
    l_info info_type_table := info_type_table();
    begin
        for i in (select  e.employeeid, 
                          e.lastname, 
                          c.customerid,
                          c.companyname,
                          o.orderid,
                          o.orderdate
                  from  ntw_employees e
                    inner join 
                        ntw_orders    o
                        on e.employeeid = o.employeeid
                    inner join 
                        ntw_customers c
                        on o.customerid = c.customerid
                  where e.city  = 'London')
        loop
            l_info.extend;
            l_info(l_info.count)  :=  (info_type(i.employeeid, i.lastname, i.customerid, i.companyname, i.orderid, i.orderdate));
            dbms_output.put_line('angajat = ' || i.employeeid);
        end loop;
    end;  
    
    有人能解释一下我的匿名区出了什么问题吗

    谢谢。

    您的函数(可能)引用了一个名为
    info\u type
    的对象类型。您的匿名块正在使用记录类型。记录类型没有构造函数。您必须单独分配每一列,并有一个记录类型变量:

    ...
        l_info_rec info_type;
    begin
        ...
        loop
            l_info.extend;
            l_info_rec.emp_no := i.employeeid;
            l_info_rec.lastname := i.lastname;
            l_info_rec.cust_no := i.customerid;
            l_info_rec.CO_name := i.companyname;
            l_info_rec.orderid := i.orderid;
            l_info_rec.orderdate := i.orderdate;
    
            l_info(l_info.count)  :=  l_info_rec;
            dbms_output.put_line('angajat = ' || i.employeeid);
        end loop;
    end;
    
    您还可以使用显式游标并使用返回以下内容的行:

    declare
        cursor c is select  e.employeeid, 
                          e.lastname, 
                          c.customerid,
                          c.companyname,
                          o.orderid,
                          o.orderdate
                  from  ntw_employees e
                    inner join 
                        ntw_orders    o
                        on e.employeeid = o.employeeid
                    inner join 
                        ntw_customers c
                        on o.customerid = c.customerid
                  where e.city  = 'London';
    
        type info_type_table is table of c%rowtype;
    
        l_info info_type_table := info_type_table();
    begin
        for r in c
        loop
            l_info.extend;
            l_info(l_info.count)  :=  r;
            dbms_output.put_line('angajat = ' || r.employeeid);
        end loop;
    end;
    /
    
    或者即使使用
    批量收集
    直接放入您的表格类型:

    declare
        cursor c is select  e.employeeid, 
                  ...
                  where e.city  = 'London';
    
        type info_type_table is table of c%rowtype;
    
        l_info info_type_table;
    begin
        open c;
        fetch c bulk collect into l_info;
        close c;
    
        for i in 1..l_info.count loop
            dbms_output.put_line('angajat = ' || l_info(i).employeeid);
        end loop;
    end;
    /
    

    。。。使用循环仅显示该表中的值。

    基本上,逐行处理类似于逐慢处理。始终尽可能使用批量收集,以避免系统性能故障。希望下面的代码片段能有所帮助

    --Function with Bulk collect
    CREATE OR REPLACE FUNCTION get_info(
        p_city VARCHAR2)
      RETURN info_type_table
    AS
      l_info info_type_table := info_type_table();
    BEGIN
      SELECT e.employeeid,
        e.lastname,
        c.customerid,
        c.companyname,
        o.orderid,
        o.orderdate 
        BULK COLLECT  -- Using bulk collect for the performance
      INTO l_info
      FROM ntw_employees e
      INNER JOIN ntw_orders o
      ON e.employeeid = o.employeeid
      INNER JOIN ntw_customers c
      ON o.customerid = c.customerid
      WHERE e.city    = p_city;
      RETURN l_info;
    END;
    
    ----Anonymous block with Bulk collect
    DECLARE
    type info_type
    IS
      record
      (
        emp_no    NUMBER(3),
        lastname  VARCHAR2(26),
        cust_no   VARCHAR2(5),
        CO_name   VARCHAR2(50),
        orderid   NUMBER(5),
        orderdate DATE );
    type info_type_table
    IS
      TABLE OF info_type;
      l_info info_type_table; -- default constructor not required in record type case
    BEGIN
      SELECT e.employeeid,
        e.lastname,
        c.customerid,
        c.companyname,
        o.orderid,
        o.orderdate
        BULK COLLECT 
        INTO 
        l_info
      FROM ntw_employees e
      INNER JOIN ntw_orders o
      ON e.employeeid = o.employeeid
      INNER JOIN ntw_customers c
      ON o.customerid = c.customerid
      WHERE e.city    = 'London';
    
      FOR I IN l_info.FIRST..l_info.LAST LOOP
      dbms_output.put_line('angajat = ' || l_info(i).employeeid);
      END LOOP;
    END; 
    

    @米卡图雷。在您的编辑中,
    extend
    仍然针对表类型,而不是记录类型。我在11gR2中运行了所有三个版本,没有错误,并且都得到了相同的输出。