$$
est juste le strict minimum pour cotation en dollars
. Rendez-le (beaucoup !) moins susceptible d'entrer en conflit avec les chaînes dans le littéral inclus en mettant une chaîne entre les dollars :
CREATE OR REPLACE FUNCTION time_to_sec(timepoint timestamp with time zone)
RETURNS bigint LANGUAGE plpgsql AS
$BODY$
DECLARE
seconds bigint;
secondsFromEpoch bigint;
secondsFromMidnight bigint;
BEGIN
secondsFromEpoch = EXTRACT(EPOCH FROM timepoint)::bigint;
secondsFromMidnight = EXTRACT(EPOCH FROM CURRENT_TIMESTAMP::date)::bigint;
seconds = secondsFromEpoch - secondsFromMidnight;
return seconds;
END;
$BODY$;
Plus de conseils
-
L'opérateur d'affectation dans plpgsql est
:=
.=
n'est pas documenté et peut disparaître dans les versions futures. Plus d'informations sous cette question connexe . -
Utilisez
CURRENT_DATE
au lieu deCURRENT_TIMESTAMP::date
. -
C'est autorisé, mais je conseillerais de ne pas utiliser de noms de paramètres à casse mixte dans plpgsql. Ils ne sont pas sensibles à la casse.
-
Plus important encore, simplifiez :
CREATE OR REPLACE FUNCTION time_to_sec2(timepoint timestamp with time zone) RETURNS bigint LANGUAGE plpgsql STABLE AS $BODY$ BEGIN RETURN EXTRACT(EPOCH FROM timepoint - current_date)::bigint; END; $BODY$;
Ou encore :
CREATE OR REPLACE FUNCTION time_to_sec3(timepoint timestamp with time zone) RETURNS bigint LANGUAGE sql AS $BODY$ SELECT EXTRACT(EPOCH FROM timepoint - current_date)::bigint; $BODY$;
-
Peut être déclaré
STABLE
!
- Il existe également la fonction étroitement liée
age()
dans PostgreSQL faisant presque, mais pas tout à fait, la même chose :il renvoie un résultat "symbolique" avec des années et des mois standard. Par conséquent, expression avecage()
peut donner des résultats différents sur de plus longues périodes.
Ceux-ci sont tous équivalents - à l'exception des deux derniers déviant avec des périodes de temps plus longues :
WITH x(t) AS (VALUES ('2012-07-20 03:51:26+02'::timestamptz))
SELECT time_to_sec(t) AS t1
,time_to_sec2(t) AS t2
,time_to_sec3(t) AS t3
,EXTRACT(EPOCH FROM t - current_date)::bigint AS t4
,EXTRACT(EPOCH FROM age(t, current_date))::bigint AS t5 -- deviates
,EXTRACT(EPOCH FROM age(t))::bigint * -1 AS t6 -- deviates
FROM x;
Quant à la question d'origine :ce message d'erreur PostgreSQL ne signifie pas nécessairement que le problème vient du signe dollar :
La plupart du temps c'est un ;
manquant avant cette ligne. Ou peut-être un caractère spécial non échappé en XML, comme < > &
? Le signe dollar $
ça devrait aller. Mais je ne suis pas un expert en fourmi. Il devrait y avoir plus de contexte dans le journal PostgreSQL.