0

我是PostgreSQL的新手,我遇到了一些問題,需要它來做我想做的事情。從Postgres函數返回數據

我需要構建一個函數,它可以接受多個變量,在內部執行多個查詢,然後返回一個由多行和幾列組成的數據集。我已經建立了幾個測試功能來獲得Postgres的功能,更好地把握,這裏是一個:

CREATE OR REPLACE FUNCTION sql_with_rows11(id integer) RETURNS character varying AS $BODY$ 
declare vid integer; 
declare vendor character varying; 
BEGIN 
vid := (select v_id from public.gc_alerts where a_id = id); 
vendor := (select v_name from public.gc_vendors where v_id = vid); 

    RETURN vendor; 
    END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
ALTER FUNCTION sql_with_rows11(integer) 
    OWNER TO postgres; 

我知道我可以合併到這一個查詢,但是這更是一個實踐鍛鍊。這工作正常,我得到供應商的名稱。但是,現在我需要返回gc_vendors表中的多個列。

最後,我需要構建一個函數,它將根據子查詢從幾個表中返回列。我研究過創建一個結果集函數,但我相信它一次只返回一行。我還研究了返回的setof類型,但似乎僅限於存在的表。

--------------編輯

嘿,夥計們,感謝您的幫助。我改變了以下功能:

CREATE OR REPLACE FUNCTION sql_with_rows14(IN v_uid character varying, IN lid   integer) 
RETURNS table (aid int, aname character varying) AS $BODY$ 
declare aid integer; 
declare aname character varying; 
BEGIN 
sql_with_rows14.aid := (select a_id from public.gc_alerts where v_id =   sql_with_rows14.v_uid); 
sql_with_rows14.aname := (select a_name from public.gc_alerts where a_id =  sql_with_rows14.aid); 

    RETURN; 
    END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 

我也嘗試過使用RETURN NEXT,但結果相同。

當我查詢它,如果查詢返回只有一行,它工作正常。但它不適用於多行。我也嘗試過這樣的結果。你們能幫忙嗎?

試過這個: BEGIN sql_with_rows14.aid:=(從public.gc_alerts中選擇a_id); sql_with_rows14.aname:=(從public.gc_alerts中選擇a_name);

RETURN NEXT; 
    END; 

回答

1

首先,考慮使用視圖或簡單查詢。我會說,如果你可以用簡單的查詢來處理某些東西,你不應該爲它創建函數。你的情況,你可以,如果你希望你的函數返回的行使用此查詢

select 
    v.v_name, v.* -- or any other columns from gc_alerts or gc_vendors 
from public.gc_alerts as a 
    inner join public.gc_vendors as v on v.v_id = a.vid 
where a.a_id = <your id here> 

,你可以聲明它像

CREATE OR REPLACE FUNCTION sql_with_rows11(id integer) 
RETURNS table(vendor text, v_id int) 
as 
$$ 
    select 
     v.v_name, v.v_id 
    from public.gc_alerts as a 
     inner join public.gc_vendors as v on v.v_id = a.vid 
    where a.a_id = id 
$$ language SQL; 

或PLPGSQL功能:

CREATE OR REPLACE FUNCTION sql_with_rows11(id integer) 
RETURNS table(vendor text, vid int) 
AS 
$$ 
    declare vid integer; 
    declare vendor character varying; 
BEGIN 
    sql_with_rows11.vid := 1; -- prefix with function name because otherwise it would be declared variables 
    sql_with_rows11.vendor := 4; 
    return next; 

    sql_with_rows11.vid := 5; 
    sql_with_rows11.vendor := 8; 
    return next; 
END; 
$$ LANGUAGE plpgsql; 

sql fiddle demo到小提琴:)

+0

喜羅馬的一章,你的答案是非常有幫助的。我試圖寫類似的東西,但是我有一個返回多行的問題。我有以下 – user2630270

+0

@ user2630270以下是什麼? –

2

我需要從gc_vendors表中返回多列

要返回單列多列(而不是一組行),你可以使用:

RETURNS row_type 

..其中row_type是一個預定義的複合類型(就像表名一樣,自動起作用)。或者:

RETURNS record 

結合OUT參數。請注意,OUT參數幾乎在任何地方都可見,並避免naming conflicts
使用第二個選項,你的函數可以是這樣的:

CREATE OR REPLACE FUNCTION sql_with_columns(
     IN _id integer -- the IN key word is just noise 
    , OUT vid integer 
    , OUT vendor text 
    ) RETURNS record AS 
$func$ 
BEGIN 

SELECT INTO vid v_id 
FROM public.gc_alerts 
WHERE a_id = id; 

SELECT INTO vendor v_name 
FROM public.gc_vendors 
WHERE v_id = vid; 

RETURN;  -- just noise, since OUT parameters are returned automatically 

END 
$func$ LANGUAGE plpgsql 

正如你所說,你應該兩個查詢合併成一個,甚至使用普通的SQL語句。這只是一個展示案例。 The excellent manual has all the details.

可以也使用

RETURNS TABLE (...) 

或者:

RETURNS SETOF row_type 

這將使您返回一組行(0,1或多個)的。但這不是你的問題。

獲得單獨列而不是記錄表示,調用一個函數一樣,有:

SELECT * FROM sql_with_columns(...)

這裏有很多的例子對SO,嘗試用標籤的搜索和一些關鍵詞。

雖然與PLPGSQL工作,還閱讀how to return from a function in the manual.

+0

我相信最後的「迴歸」可以在「sql_with_columns」函數中省略。 – bma

+0

@bma:我的評論說的很多,不是嗎? [Pavel](http://pubstream.com/users/406691/pavel-stehule)(plpgsql的主要貢獻者)更喜歡顯式的'RETURN',即使在示例中不需要。 –

+0

它的確如此。我不應該提到這一點,從你的「噪音」評論中可以看出,它沒有任何用處。抱歉。 – bma