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

Postgres now() vs 'now' in Funktion

Es ist kein Fehler, es ist ein Feature... Hier gibt es zwei Punkte.

  1. Ersetzung von 'jetzt'

    Werfen wir einen Blick in die Dokumentation (Date /Zeitfunktionen und Operatoren ):

    Also 'now' wird zum Parsing-Zeitpunkt in einen Zeitstempel umgewandelt.

  2. Vorbereitete Erklärungen

    Okay, aber was bedeutet es in Bezug auf Funktionen? Es ist einfach zu demonstrieren, dass eine Funktion bei jedem Aufruf interpretiert wird:

    t=# create function test() returns timestamp as $$
    begin
     return 'now';
    end;
    $$ language plpgsql;
    CREATE FUNCTION
    
    t=# select test();
               test            
    ----------------------------
     2015-12-11 11:14:43.479809
    (1 row)
    
    t=# select test();
               test            
    ----------------------------
     2015-12-11 11:14:47.350266
    (1 row)
    

    In diesem Beispiel 'now' verhält sich wie erwartet.

    Was ist der Unterschied? Ihre Funktion verwendet SQL-Anweisungen und test() nicht. Schauen wir uns noch einmal die Dokumentation an (PL/ pgSQL-Plan-Caching ):

    Und hier (Erklärung vorbereiten ):

    Daher 'now' wurde beim Analysieren der vorbereiteten Anweisung in einen Zeitstempel konvertiert. Lassen Sie uns dies demonstrieren, indem wir eine vorbereitete Anweisung außerhalb einer Funktion erstellen:

    t=# prepare s(integer) as UPDATE test_date_bug SET date2 = 'now' WHERE id = $1;
    PREPARE
    
    t=# execute s(1);
    UPDATE 1
    t=# execute s(2);
    UPDATE 1
    
    t=# select * from test_date_bug;
     id |             date1             |             date2
    ----+-------------------------------+-------------------------------
      3 | 2015-12-11 11:01:38.491656+03 | infinity
      1 | 2015-12-11 11:01:37.91818+03  | 2015-12-11 11:40:44.339623+03
      2 | 2015-12-11 11:01:37.931056+03 | 2015-12-11 11:40:44.339623+03
    (3 rows)
    

Das ist passiert. 'now' wurde einmal in einen Zeitstempel konvertiert (als die vorbereitete Anweisung geparst wurde) und now() wurde zweimal angerufen.