Това, което се опитвате да направите, може да работи по следния начин:
Редактирайте с допълнителна информация
CREATE OR REPLACE FUNCTION f_products_per_month()
RETURNS SETOF fcholder AS
$BODY$
DECLARE
r fcholder;
BEGIN
FOR r.y, r.m IN
SELECT to_char(x, 'YYYY')::int4 -- AS y
,to_char(x, 'MM')::int4 -- AS m
FROM (SELECT '2008-01-01 0:0'::timestamp
+ (interval '1 month' * generate_series(0,57)) AS x) x
LOOP
RETURN QUERY
SELECT * -- use '*' in this case to stay in sync
FROM get_forecast_history(r.m, r.y);
IF NOT FOUND THEN
RETURN NEXT r;
END IF;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql;
Обаждане:
SELECT * FROM f_products_per_month();
Основни точки:
- Последна редакция за включване на иначе празен ред за месеци без продукти.
- Написахте „LEFT JOIN“, но не може да работи така.
- Има няколко начина да направите това, но
RETURN QUERY
е най-елегантният. - Използвайте същия тип връщане, както използва вашата функция get_forecast_history().
- Избягвайте конфликти на имената с OUT параметрите, като квалифицирате имената на колоните в таблица (вече не е приложимо във финалната версия).
- Не използвайте
DATE '2008-01-01'
, използвайте клеймо за време, както направих аз, така или иначе трябва да се преобразува за to_char(). По-малко кастинг, представя се по-добре (не че има голямо значение в този случай). '2008-01-01 0:0'::timestamp
иtimestamp '2008-01-01 0:0'
са само два варианта на синтаксис, които правят едно и също.- За по-стари версии на PostgreSQL езикът plpgsql не е инсталиран по подразбиране. Може да се наложи да издадете
CREATE LANGUAGE plpgsql;
веднъж във вашата база данни. Вижте ръководството тук .
Вероятно бихте могли да опростите двете си функции в една заявка или функция, ако искате.