PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Postgres now() vs 'now' na função


Não é um bug, é um recurso... Há dois pontos aqui.

  1. Substituição de 'agora'

    Vamos dar uma olhada na documentação (Data /Funções e operadores de tempo ):

    Então 'now' é convertido em um carimbo de data/hora no momento da análise.

  2. Declarações preparadas

    Ok, mas o que isso significa em relação às funções? É fácil demonstrar que uma função é interpretada cada vez que você a chama:
    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)
    

    Neste exemplo 'now' se comporta como você esperava.

    Qual é a diferença? Sua função usa instruções SQL e test() não. Vamos examinar a documentação novamente (PL/ Cache de plano pgSQL ):

    E aqui (Preparar Declaração ):

    Portanto, 'now' foi convertido em um carimbo de data/hora quando a instrução preparada foi analisada. Vamos demonstrar isso criando uma instrução preparada fora de uma função:
    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)
    

Isso é o que aconteceu. 'now' foi convertido para um timestamp uma vez (quando a instrução preparada foi analisada) e now() foi chamado duas vezes.