PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Executar arquivo com SQLExec contendo caracteres $$


$$ é 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 .

  • Use CURRENT_DATE em vez de CURRENT_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 declarado STABLE !
  • 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 com age() 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.