Es ist kein Fehler, es ist ein Feature... Hier gibt es zwei Punkte.
-
Ersetzung von 'jetzt'
Werfen wir einen Blick in die Dokumentation (Date /Zeitfunktionen und Operatoren ):
Also
'now'
wird zum Parsing-Zeitpunkt in einen Zeitstempel umgewandelt. -
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.