2011-11-28 918 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复制)