Quello che stai cercando di fare potrebbe funzionare in questo modo:
Modifica con informazioni aggiuntive
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;
Chiama:
SELECT * FROM f_products_per_month();
Punti principali:
- Modifica finale per includere una riga altrimenti vuota per mesi senza prodotti.
- Hai scritto "LEFT JOIN", ma non è così che può funzionare.
- Ci sono diversi modi per farlo, ma
RETURN QUERY
è il più elegante. - Utilizza lo stesso tipo di ritorno utilizzato dalla tua funzione get_forecast_history().
- Evita i conflitti di denominazione con i parametri OUT qualificando come tabella i nomi delle colonne (non più applicabili nella versione finale).
- Non utilizzare
DATE '2008-01-01'
, usa un timestamp come ho fatto io, deve comunque essere convertito per to_char(). Meno casting, prestazioni migliori (non che importi molto in questo caso). '2008-01-01 0:0'::timestamp
etimestamp '2008-01-01 0:0'
sono solo due varianti di sintassi che fanno lo stesso.- Per le versioni precedenti di PostgreSQL il linguaggio plpgsql non è installato di default. Potrebbe essere necessario emettere
CREATE LANGUAGE plpgsql;
una volta nel tuo database. Vedi il manuale qui .
Probabilmente potresti semplificare le tue due funzioni in una query o funzione, se lo desideri.