2014-03-13 78 views
0

這裏是場景。我想根據記錄計數返回一個結果集。例如:Postgres中頻控制結構選擇

DO 
$BODY$ 
IF (SELECT count(*) < 50 FROM (
SELECT * FROM (SELECT col1, col2, col3 FROM v_my_view) AS cnt;) 
THEN 
SELECT * FROM (SELECT col1, col2, col3 FROM v_my_view) AS qry; 
ELSE (
SELECT *, NTILE(5) OVER (ORDER BY col1 DESC) AS my_tile FROM (
SELECT col1, col2, col3 FROM v_my_view) AS tileme;) 
END IF; 
END; 
$BODY$ 

請注意,語法是近似的,但意圖應該是顯而易見的。如果記錄集很小,則返回查詢,否則返回一個有爭議的查詢。我有各種錯誤信息試圖執行此操作,其中包括:

在非SETOF功能不能使用返回查詢

查詢沒有目的地的結果數據

此外,我知道你不應該在生產代碼中使用*。

回答

0

問題是,您根本無法從DO聲明中返回行。您需要使用聲明爲RETURN類型的函數。要允許程序性內容,使用LANGUAGE plpgsql(這也是DO語句的默認值):

CREATE OR REPLACE FUNCTION foo() 
    RETURNS TABLE(col1 text, col2 text, col3 text, my_tile int) AS 
$func$ 
BEGIN 

    IF (SELECT count(*) < 50 FROM v_my_view) THEN 
     RETURN QUERY 
     SELECT v.col1, v.col2, v.col3, 0 AS my_tile 
     FROM v_my_view v; 
    ELSE 
     RETURN QUERY 
     SELECT v.col1, v.col2, v.col3, ntile(5) OVER (ORDER BY v.col1 DESC) 
     FROM v_my_view v; 
    END IF; 
END 
$func$ LANGUAGE sql STABLE; 

RETURNS子句中的數據類型必須匹配您的實際數據類型。查詢中的列別名在結果中不可見,而是使用RETURNS子句中聲明的名稱。

此外,count(*)是完美的語法。

這可以用一個簡單的查詢和CASE聲明的最後一列所取代,但...