PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Exécuter le fichier avec SQLExec contenant les caractères $$

$$ 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 de CURRENT_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 avec age() 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.