2016-06-01 30 views
4

私は2つの状況では、レコードのテーブルを返すようにしようとしています:無名ブロック を使用して機能 PLS-00222:名「INFO_TYPE」が無い関数は、この範囲内に存在する

  • を使用して

    1. 私はこの関数を使用していますが、すべて正常に動作していますが、私は匿名ブロックに変換しようとしているときに上記のエラーが表示されます。ここ は、コードは次のとおりです。関数の場合

      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; 
      

      誰もが、私の無名ブロックで間違っているものを私にしてください説明できますか?

      ありがとうございます。

  • 答えて

    5

    あなたの機能はおそらくinfo_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; 
    /
    

    あるいはとbulk collectを真っ直ぐにし、あなたは個別に各列を割り当て、レコード型の変数を持っている必要があなたのテーブルタイプ:

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

    ...このテーブルの値を表示するだけのループです。

    +0

    @mikcutu - 再。 'extend'はまだレコードタイプではなく、テーブルタイプに対してです。エラーなしで11gR2の3つのバージョンをすべて実行し、すべて同じ出力を得ました。 –

    1

    基本的に行単位の処理は、低速処理と同様です。常にシステムパフォーマンスの不具合を避けるために可能な限りBULKを使用してください。スニペットの下の希望が役立ちます。

    --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; 
    
    関連する問題