4

我試圖創建a PL/pgSQL function,它應該填充一個臨時表,然後從它返回所有行(稍後它將成爲一個連接),但我不知道哪個返回類型指定它:如何創建返回多行的PL/pgSQL函數

create or replace function pref_daily_misere() returns void as $BODY$ 
     begin 

     create temporary table temp_best (id varchar not null) on commit drop; 
     insert into temp_best (id) select id from pref_money where 
      yw = to_char(current_timestamp - interval '1 week', 'IYYY-IW') 
      order by money desc limit 10; 
     select id from temp_best; 
     end; 
$BODY$ language plpgsql; 

上述工作的陳述自己的,但給我的錯誤

# select pref_daily_misere(); 
ERROR: query has no destination for result data 
HINT: If you want to discard the results of a SELECT, use PERFORM instead. 
CONTEXT: PL/pgSQL function "pref_daily_misere" line 7 at SQL statement 

當我嘗試調用它在我的PostgreSQL數據庫8.4.11。

這可能是因爲我錯誤地指定了返回上面的void,但我不知道使用哪種返回類型,而忽略返回類型是編譯錯誤。

+1

是否有任何理由將上述內容隱藏起來?一個視圖(或CTE)似乎非常適合,恕我直言。 (可能除了醜陋的限制) – wildplasser

+0

這不是一個完整的功能,我會在稍後添加更多的東西。 –

回答

5

你想使用一個setof varchar返回類型,然後return query ...裏面的函數。來自fine manual

39.6.1.2。 RETURN NEXT和RETURN QUERY

RETURN NEXT expression; 
RETURN QUERY query; 
RETURN QUERY EXECUTE command-string [ USING expression [, ... ] ]; 

當一個PL/pgSQL函數聲明爲返回SETOFsometype。這時候,遵循的程序略有不同。在這種情況下,要返回的各個項目由一系列RETURN NEXTRETURN QUERY命令指定,然後使用不帶參數的最後一個RETURN命令指示函數已完成執行。

我想你想要更多的東西是這樣的:

create or replace function pref_daily_misere() returns setof varchar as $BODY$ 
begin 
    create temporary table temp_best (id varchar not null) on commit drop; 
    insert into temp_best (id) 
    select id 
    from pref_money 
    where yw = to_char(current_timestamp - interval '1 week', 'IYYY-IW') 
    order by money 
    desc limit 10; 
    return query select id from temp_best; 
    return; 
end; 
$BODY$ language plpgsql; 

但是,臨時表是在這裏毫無意義:

注:目前執行的RETURN NEXTRETURN QUERY存儲如上所述,在從函數返回之前的整個結果集。

因此PostgreSQL正在計算整個結果集並自行緩存它。你可以這樣做:

create or replace function pref_daily_misere() returns setof varchar as $BODY$ 
begin 
    return query 
     select id 
     from pref_money 
     where yw = to_char(current_timestamp - interval '1 week', 'IYYY-IW') 
     order by money 
     desc limit 10; 
    return; 
end; 
$BODY$ language plpgsql; 

我敢肯定的臨時表將要在你的函數結束反正下降,所以你應該擺脫它。

+0

謝謝,但爲什麼第二個'返回'是必要的?我已經評論過它,它似乎工作正常。 –

+2

@AlexanderFarber:第二個'return;'不是必須的,但文檔聲明「沒有參數的最終'RETURN'命令用於表示函數已經完成執行」,所以我把它放在避免關於它爲什麼的問題上不在那裏:) –