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

Postgres now() vs 'now' en fonction

Ce n'est pas un bug, c'est une fonctionnalité... Il y a deux points ici.

  1. Remplacement de 'maintenant'

    Regardons la documentation (Date /Fonctions et opérateurs de temps ):

    Donc 'now' est converti en horodatage au moment de l'analyse.

  2. Relevés préparés

    D'accord, mais qu'est-ce que cela signifie en ce qui concerne les fonctions ? Il est facile de démontrer qu'une fonction est interprétée à chaque fois que vous l'appelez :

    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)
    

    Dans cet exemple 'now' se comporte comme prévu.

    Quelle est la différence? Votre fonction utilise des instructions SQL, contrairement à test(). Examinons à nouveau la documentation (PL/ Mise en cache du plan pgSQL ):

    Et ici (Préparer la déclaration ):

    D'où 'now' a été converti en horodatage lorsque l'instruction préparée a été analysée. Démontrons cela en créant une instruction préparée en dehors d'une fonction :

    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)
    

C'est ce qui s'est passé. 'now' a été converti en horodatage une fois (lorsque l'instruction préparée a été analysée) et now() a été appelé deux fois.