Хранимая функция с временной таблицей в postgresql - PullRequest
2 голосов
/ 28 ноября 2011

Я новичок в написании хранимых функций в postgresql и вообще. Я пытаюсь написать onw с входным параметром и вернуть набор результатов, хранящихся во временной таблице. Я делаю следующее в своей функции. 1) Получить список всех потребителей и сохранить их идентификаторы, хранящиеся во временной таблице. 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 ]

4 голосов
/ 28 ноября 2011

AFAIK Нельзя объявлять таблицы как переменные в postgres.Что вы можете сделать, так это создать его в своем функциональном теле и использовать его через себя (или даже вне функции).Однако будьте осторожны, поскольку временные таблицы не удаляются до конца сеанса или фиксации.

Для этого нужно использовать RETURN NEXT или RETURN QUERY

Что касается типа результата функции, я всегда считал RETURNS TABLE более читабельным.

edit: Ваш массив 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-Maximum, поскольку именно это вы имеете здесь в виду.

0 голосов
/ 28 ноября 2011

может быть проще просто вернуть таблицу (или запрос)

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 )

...