PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Postgres now() vs 'now' in funzione

Non è un bug, è una funzionalità... Ci sono due punti qui.

  1. Sostituzione di 'ora'

    Diamo un'occhiata alla documentazione (Data /Funzioni temporali e operatori ):

    Quindi 'now' viene convertito in un timestamp al momento dell'analisi.

  2. Dichiarazioni preparate

    Va bene, ma cosa significa per quanto riguarda le funzioni? È facile dimostrare che una funzione viene interpretata ogni volta che la chiami:

    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 questo esempio 'now' si comporta come ti aspettavi.

    Qual è la differenza? La tua funzione usa le istruzioni SQL e test() no. Esaminiamo nuovamente la documentazione (PL/ pgSQL Pianifica la memorizzazione nella cache ):

    E qui (Preparare la dichiarazione ):

    Quindi 'now' è stato convertito in un timestamp durante l'analisi dell'istruzione preparata. Dimostriamolo creando un'istruzione preparata al di fuori di una funzione:

    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)
    

Questo è quello che è successo. 'now' è stato convertito in un timestamp una volta (quando l'istruzione preparata è stata analizzata) e now() è stato chiamato due volte.