$$
is slechts het absolute minimum voor dollar-quotering
. Maak het (veel!) minder waarschijnlijk dat het conflicteert met strings in de bijgevoegde letterlijke tekst door een string tussen de dollars te plaatsen:
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$;
Meer advies
-
De toewijzingsoperator in plpgsql is
:=
.=
is niet gedocumenteerd en kan in toekomstige releases verdwijnen. Meer onder deze gerelateerde vraag . -
Gebruik
CURRENT_DATE
in plaats vanCURRENT_TIMESTAMP::date
. -
Het is toegestaan, maar ik zou adviseren om geen parameternamen met gemengde hoofdletters te gebruiken in plpgsql. Ze zijn niet hoofdlettergevoelig.
-
Het belangrijkste is:vereenvoudig :
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$;
Of zelfs:
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$;
-
Kan worden verklaard
STABLE
!
- Er is ook de nauw verwante functie
age()
in PostgreSQL doet bijna, maar niet helemaal hetzelfde:het geeft een "symbolisch" resultaat met standaardjaren en maanden. Daarom, expressie metage()
kan gedurende langere tijd verschillende resultaten opleveren.
Deze zijn allemaal gelijkwaardig - behalve de laatste twee die met langere tijdsperioden afwijken:
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;
Wat betreft de oorspronkelijke vraag:deze PostgreSQL-foutmelding betekent niet noodzakelijk dat het probleem bij het dollarteken ligt:
Meestal is het een ontbrekende ;
voor die lijn. Of misschien speciale tekens zonder escapecodes in XML, zoals < > &
? Het dollarteken $
zou goed moeten zijn. Maar ik ben geen expert met mieren. Er zou meer context in het PostgreSQL-logboek moeten staan.