2011-11-28 915 views
2

我是在postgresql和一般情況下編寫存儲函數的新手。我正在嘗試使用輸入參數編寫onw,並返回存儲在臨時表中的一組結果。 我在我的功能中執行以下操作。 1)獲取所有消費者的列表並將其ID存儲在臨時表中。 2)遍歷一個特定的表,並從上面的列表中檢索對應於每個值的值,並存儲在臨時表中。 3)返回臨時表。在postgresql中使用臨時表存儲函數

這裏,我已經嘗試自己寫的功能,

create or replace function getPumps(status varchar) returns setof record as $$ (setof record?) 
DECLARE 
cons_id integer[]; 
i integer; 
temp table tmp_table;--Point B 
BEGIN 
select consumer_id into cons_id from db_consumer_pump_details; 
FOR i in select * from cons_id LOOP 
    select objectid,pump_id,pump_serial_id,repdate,pumpmake,db_consumer_pump_details.status,db_consumer.consumer_name,db_consumer.wenexa_id,db_consumer.rr_no into tmp_table from db_consumer_pump_details inner join db_consumer on db_consumer.consumer_id=db_consumer_pump_details.consumer_id 
where db_consumer_pump_details.consumer_id=i and db_consumer_pump_details.status=$1--Point A 
order by db_consumer_pump_details.consumer_id,pump_id,createddate desc limit 2 
END LOOP; 
return tmp_table 
END; 
$$ 
LANGUAGE plpgsql; 

但林不知道我的方法以及是否在A點和B IM權利,我已經標註在上面的代碼。在嘗試創建臨時表時遇到一些錯誤。

編輯:得到了可以工作的函數,但是當我嘗試運行該函數時出現以下錯誤。

ERROR: array value must start with "{" or dimension information 

這是我的修改函數。

create temp table tmp_table(objectid integer,pump_id integer,pump_serial_id varchar(50),repdate timestamp with time zone,pumpmake varchar(50),status varchar(2),consumer_name varchar(50),wenexa_id varchar(50),rr_no varchar(25)); 

    select consumer_id into cons_id from db_consumer_pump_details; 
    FOR i in select * from cons_id LOOP 
insert into tmp_table 
select objectid,pump_id,pump_serial_id,repdate,pumpmake,db_consumer_pump_details.status,db_consumer.consumer_name,db_consumer.wenexa_id,db_consumer.rr_no from db_consumer_pump_details inner join db_consumer on db_consumer.consumer_id=db_consumer_pump_details.consumer_id where db_consumer_pump_details.consumer_id=i and db_consumer_pump_details.status=$1 
order by db_consumer_pump_details.consumer_id,pump_id,createddate desc limit 2; 
END LOOP; 
return query (select * from tmp_table); 
drop table tmp_table; 
    END; 
    $$ 
    LANGUAGE plpgsql; 
+0

如果你願意,你可以返回行集,而不是臨時表 – triclosan

+0

@triclosan,你能舉個例子嗎? – KodeSeeker

+0

'create function GetEmployees()將setof employee返回爲select * from employee;'語言'sql';'從這個wiki:http://wiki.postgresql.org/wiki/Return_more_than_one_row_of_data_from_PL/pgSQL_functions – triclosan

回答

3

AFAIK一個不能申報表作爲Postgres的變量。你可以做的是在你的功能主體中創建一個並且使用它(甚至在功能之外)。請注意,臨時表不會在會話結束或提交之前丟失。

去的方式是使用RETURN NEXT or RETURN QUERY

至於功能上的結果類型我總是發現退貨表更易讀。

編輯: 您的cons_id數組是不必要的,只是迭代select返回的值。 另外,您可以在單個函數中有多個返回查詢語句,以將查詢結果追加到函數返回的結果中。

你的情況:

CREATE OR REPLACE FUNCTION getPumps(status varchar) 
RETURNS TABLE (objectid INTEGER,pump_id INTEGER,pump_serial_id INTEGER....) 
AS 
$$ 
BEGIN 
    FOR i in SELECT consumer_id FROM db_consumer_pump_details LOOP 

    RETURN QUERY(
     SELECT objectid,pump_id,pump_serial_id,repdate,pumpmake,db_consumer_pump_details.status,db_consumer.consumer_name,db_consumer.wenexa_id,db_consumer.rr_no FROM db_consumer_pump_details INNER JOIN db_consumer ON db_consumer.consumer_id=db_consumer_pump_details.consumer_id 
     WHERE db_consumer_pump_details.consumer_id=i AND db_consumer_pump_details.status=$1 
     ORDER BY db_consumer_pump_details.consumer_id,pump_id,createddate DESC LIMIT 2 
    ); 
    END LOOP; 
END; 
$$ 

EDIT2:

你可能想看一看GroupWise的-K-最大問題this解決方案,這就是你打交道正是在這裏。

+0

你看看我貼的編輯嗎? – KodeSeeker

+0

是的,看我的編輯 – soulcheck

+0

,謝謝!這很好地適用於一些修改,一個不相關的問題,有沒有辦法獲取上述查詢返回的記錄總數?顯然數(*)不會工作。 – KodeSeeker

0

它可能更容易只返回一個表(或查詢)

CREATE FUNCTION extended_sales(p_itemno int) 
RETURNS TABLE(quantity int, total numeric) AS $$ 
BEGIN 
    RETURN QUERY SELECT quantity, quantity * price FROM sales 
      WHERE itemno = p_itemno; 
END; 
$$ LANGUAGE plpgsql; 

(從postgresql docs複製)