PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Führen Sie eine Datei mit SQLExec aus, die $$-Zeichen enthält

$$ ist nur das absolute Minimum für Dollarnotierung . Machen Sie es (viel!) weniger wahrscheinlich, dass es zu Konflikten mit Strings im eingeschlossenen Literal kommt, indem Sie einen String zwischen die Dollars setzen:


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$;

Weitere Ratschläge

  • Der Zuweisungsoperator in plpgsql ist := . = ist undokumentiert und kann in zukünftigen Versionen verschwinden. Mehr unter dieser verwandten Frage .

  • Verwenden Sie CURRENT_DATE statt CURRENT_TIMESTAMP::date .

  • Es ist erlaubt, aber ich würde davon abraten, Parameternamen in plpgsql mit Groß-/Kleinschreibung zu verwenden. Groß-/Kleinschreibung wird nicht beachtet.

  • Am wichtigsten ist, vereinfachen :

    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$;
    

    Oder sogar:

    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$;
    
  • Kann als STABLE deklariert werden !

  • Es gibt auch die eng verwandte Funktion age() in PostgreSQL fast, aber nicht ganz dasselbe:Es gibt ein "symbolisches" Ergebnis mit Standardjahren und -monaten zurück. Daher Ausdruck mit age() kann über längere Zeiträume zu unterschiedlichen Ergebnissen führen.

Diese sind alle gleichwertig - bis auf die letzten beiden abweichenden mit längeren Zeiträumen:

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;

Zur ursprünglichen Frage:Diese PostgreSQL-Fehlermeldung bedeutet nicht unbedingt, dass das Problem beim Dollarzeichen liegt:

Meistens ist es ein fehlender ; vor dieser Zeile. Oder vielleicht ein nicht maskiertes Sonderzeichen in XML, wie < > & ? Das Dollarzeichen $ sollte gut sein. Aber ich bin kein Experte für Ameisen. Das PostgreSQL-Protokoll sollte mehr Kontext enthalten.