2016-03-28 7 views
0

WHILE LOOPを使用してテーブルのデータをINSERTに変換し、次にSELECTを使用するPOSTGRESQL関数を作成しようとしています。WHILE LOOPセクションの後にPostgreSQL関数からSETOF行を返します

これはSQLの例です。私は、このエラーを示しており、select get_levels_test (3)

CREATE OR REPLACE FUNCTION get_levels_test (maxlevel int) RETURNS SETOF list_of_levels AS $$ 
DECLARE 
    level int = 1; 
BEGIN 
TRUNCATE list_of_levels; 

WHILE (level <= maxlevel) LOOP 
    INSERT INTO list_of_levels 
     SELECT level;    

    level = level + 1; 
END LOOP; 
    select * from list_of_levels; 
END; 
$$ LANGUAGE PLPGSQL VOLATILE; 

それから私は、この関数を呼び出そう

ERROR: query has no destination for result data 
Hint: If you want to discard the results of a SELECT, use PERFORM instead. 
Where: PL/pgSQL function "get_levels_test" line 12 at SQL statement 

list_of_levelsテーブルがちょうどint列が含まれています。

これが必要な場合は、PostgreSQL 8.2.15(Greenplum Database 4.3.3.1 build 1)を使用しています。

答えて

0

"return next"を使用する必要があります。これは複合型またはテーブルで使用できます。この機能を使用する際にパフォーマンス上の問題が生じる可能性があるため、この機能は慎重に使用してください。結果を他のテーブルに結合するためにこれを使用しないでください。これで大きなデータセットを返さないでください。短いレポートのような非常に小さな結果にのみ使用してください。

また、例外処理を関数に追加する必要があります。私はこれを以下の私の関数に追加しました。

例テーブル:

create table employees 
    (id int not null, 
    manager_id int null, 
    employee_title text not null) 
    distributed by (id); 

例データ:

insert into employees values 
    (1, null, 'President'), 
    (2, 1, 'Vice-President'), 
    (3, 2, 'Manager'), 
    (4, 3, 'Engineer'), 
    (5, null, 'CMO'), 
    (6, 5, 'Director'), 
    (7, 6, 'Assistant'), 
    (8, 7, 'Developer'); 

機能:

create or replace function get_employees(p_id int) returns setof employees as 
    $$ 
    declare 
      v_function_name text := 'get_employees'; 
      v_location int; 
      v_rec record; 
      v_rec2 employees; 
      v_id employees.id%type; 
    begin 
      v_location := 1000; 
      create temporary table t1 
      (id integer) on commit drop distributed by (id); 

      v_location := 2000; 
      for v_rec in (select id from employees where id = p_id and manager_id is null order by id) loop 
        v_id := v_rec.id; 
        insert into t1 values (v_id); 
        while v_id is not null loop 
          select id into v_id from employees where manager_id = v_id; 
          if v_id is not null then 
            insert into t1 values (v_id); 
          end if; 
        end loop; 
      end loop; 

      v_location := 3000; 
      for v_rec2 in (select * from employees e join t1 on e.id = t1.id order by e.id) loop 
        return next v_rec2; 
      end loop; 
    exception 
     when others then 
     raise exception '(%:%:%)', v_function_name, v_location, sqlerrm; 
    end; 
    $$ 
    language plpgsql; 

と機能を使用して:

select * From get_employees(1); 
    id | manager_id | employee_title 
    ----+------------+---------------- 
     1 |   | President 
     2 |   1 | Vice-President 
     3 |   2 | Manager 
     4 |   3 | Engineer 
    (4 rows) 


    select * From get_employees(5); 
    id | manager_id | employee_title 
    ----+------------+---------------- 
     5 |   | CMO 
     6 |   5 | Director 
     7 |   6 | Assistant 
     8 |   7 | Developer 
    (4 rows) 
関連する問題