Débogage
Ce que fait votre fonction pourrait être fait beaucoup plus simple. La cause réelle de l'erreur de syntaxe est ici :
SELECT EXTRACT(day FROM TIMESTAMP startDate - endDate) INTO diffDatePart;
Il semble que vous essayez de caster startDate
à timestamp
, ce qui est un non-sens pour commencer, car votre paramètre startDate
est déclaré comme timestamp
déjà.
Cela ne fonctionne pas non plus. Je cite le manuel ici :
Cela serait fonctionne comme ceci :
SELECT EXTRACT(day FROM startDate - endDate)::int INTO diffDatePart;
Mais cela n'aurait toujours pas beaucoup de sens. Vous parlez de "dates", mais définissez toujours vos paramètres comme timestamp
. Vous pourriez désinfectez ce que vous avez comme ceci :
CREATE OR REPLACE FUNCTION f_date_diff()
RETURNS int AS
$BODY$
DECLARE
start_date date;
end_date date;
date_diff int;
BEGIN
SELECT evt_start_date FROM events WHERE evt_id = 5 INTO start_date;
SELECT evt_start_date FROM events WHERE evt_id = 6 INTO end_date;
date_diff := (endDate - startDate);
RETURN date_diff;
END
$BODY$ LANGUAGE plpgsql;
DECLARE
nécessaire une seule fois.date
colonnes déclarées avec le type appropriédate
.- N'utilisez pas d'identifiants à casse mixte, sauf si vous savez exactement ce que vous faites.
- Soustrayez le début de la fin pour obtenir un nombre positif ou appliquer l'opérateur de valeur absolue
@
. -
Depuis la soustraction des dates (au lieu de soustraire les horodatages , ce qui donne un
interval
) donne déjàinteger
, simplifier :SELECT (startDate - endDate) INTO diffDatePart;
Ou encore plus simple comme affectation plpgsql :
diffDatePart := (startDate - endDate);
Requête simple
Vous pouvez résoudre la tâche simple avec une requête simple - en utilisant une sous-requête :
SELECT (SELECT evt_start_date
FROM events
WHERE evt_id = 6)
- evt_start_date AS date_diff
FROM events
WHERE evt_id = 5;
Ou vous pouvez CROSS JOIN
la table de base à elle-même (1 ligne de chaque instance, donc ça va):
SELECT e.evt_start_date - s.evt_start_date AS date_diff
FROM events e
,events s
WHERE e.evt_id = 6
AND s.evt_id = 5;
Fonction SQL
Si vous insistez sur une fonction dans ce but, utilisez une simple fonction sql :
CREATE OR REPLACE FUNCTION f_date_diff(_start_id int, _end_id int)
RETURNS int LANGUAGE sql AS
$func$
SELECT e.evt_start_date - s.evt_start_date
FROM events s, events e
WHERE s.evt_id = $1
AND e.evt_id = $2
$func$;
Appel :
SELECT f_date_diff(5, 6);
Fonction PL/pgSQL
Si vous insistez sur plpgsql ...
CREATE OR REPLACE FUNCTION f_date_diff(_start_id int, _end_id int)
RETURNS int LANGUAGE plpgsql AS
$func$
BEGIN
RETURN (SELECT evt_start_date
- (SELECT evt_start_date FROM events WHERE evt_id = _start_id)
FROM events WHERE evt_id = _end_id);
END
$func$;
Même appel.