在postgresql中使用临时表存储函数

时间:2011-11-28 12:48:53

标签: postgresql stored-procedures stored-functions

我很想在postgresql中编写存储的函数。我正在尝试使用输入参数编写onw并返回存储在临时表中的一组结果。 我在我的功能中执行以下操作。 1)获取所有消费者的列表并将他们的id存储在临时表中。 2)迭代特定表并从上面的列表中检索与每个值对应的值并存储在临时表中。 3)返回临时表。

这是我自己尝试写的功能,

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点。并且在尝试创建临时表时遇到了大量错误。

编辑:让函数正常工作,但是当我尝试运行该函数时出现以下错误。

   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;

2 个答案:

答案 0 :(得分:4)

AFAIK无法在postgres中将表声明为变量。你可以做的是在你的功能体中创建一个并通过它(甚至在功能之外)使用它。请注意,因为临时表在会话结束或提交之前不会被删除。

要走的路是使用RETURN NEXT or RETURN QUERY

对于函数结果类型,我总是发现RETURNS TABLE更具可读性。

修改 您的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:

您可能希望查看this解决方案,了解groupwise-k-maximum问题,因为这正是您在此处理的问题。

答案 1 :(得分: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复制)