$$
é apenas o mínimo para cotações em dólares
. Torne (muito!) menos provável de entrar em conflito com strings no literal incluído, colocando uma string entre os dólares:
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$;
Mais conselhos
-
O operador de atribuição em plpgsql é:=
.=
não está documentado e pode desaparecer em versões futuras. Mais nesta pergunta relacionada .
-
UseCURRENT_DATE
em vez deCURRENT_TIMESTAMP::date
.
-
É permitido, mas eu aconselharia não usar nomes de parâmetros de maiúsculas e minúsculas em plpgsql. Eles não diferenciam maiúsculas de minúsculas.
-
Mais importante ainda, simplifique :
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 ainda:
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$;
-
Pode ser declaradoSTABLE
!
- Há também a função intimamente relacionada
age()
no PostgreSQL fazendo quase, mas não exatamente, o mesmo:ele retorna um resultado "simbólico" com anos e meses padrão. Portanto, expressão comage()
pode gerar resultados diferentes por períodos mais longos.
Estes são todos equivalentes - exceto os dois últimos que se desviam com períodos de tempo mais longos:
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;
Quanto à pergunta original:esta mensagem de erro do PostgreSQL não significa necessariamente que o problema é com o cifrão:
Na maioria das vezes está faltando um
;
antes dessa linha. Ou talvez um caractere especial sem escape em XML, como < > &
? O cifrão $
deve estar bem. Mas não sou especialista em formigas. Deve haver mais contexto no log do PostgreSQL.