$$
to tylko absolutne minimum dla cytowanie dolara
. Zmniejsz prawdopodobieństwo konfliktu (znacznie!) z ciągami znaków w załączonym literale, umieszczając ciąg między dolarami:
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$;
Więcej porad
-
Operator przypisania w plpgsql to
:=
.=
jest nieudokumentowany i może zniknąć w przyszłych wydaniach. Więcej w tym powiązanym pytaniu . -
Użyj
CURRENT_DATE
zamiastCURRENT_TIMESTAMP::date
. -
Jest to dozwolone, ale radzę nie używać nazw parametrów z mieszanymi wielkościami liter w plpgsql. Wielkość liter nie jest rozróżniana.
-
Co najważniejsze, uprość :
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$;
Lub nawet:
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$;
-
Można zadeklarować
STABLE
!
- Istnieje również ściśle powiązana funkcja
age()
w PostgreSQL robi prawie to samo, ale nie do końca:zwraca "symboliczny" wynik ze standardowymi latami i miesiącami. Dlatego wyrażenie zage()
może dawać różne wyniki przez dłuższy czas.
Wszystkie są równoważne - z wyjątkiem dwóch ostatnich różniących się dłuższymi okresami czasu:
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;
Co do pierwotnego pytania:ten komunikat o błędzie PostgreSQL niekoniecznie oznacza problem ze znakiem dolara:
W większości przypadków jest to brakujący ;
przed tą linią. A może niezmienione znaki specjalne w XML, takie jak < > &
? Znak dolara $
powinno być dobrze. Ale nie jestem ekspertem od mrówek. W dzienniku PostgreSQL powinno być więcej kontekstu.