sql >> Base de Datos >  >> RDS >> PostgreSQL

Postgres ahora() vs 'ahora' en función

No es un error, es una característica... Hay dos puntos aquí.

  1. Sustitución de 'ahora'

    Echemos un vistazo a la documentación (Date /Funciones de tiempo y operadores ):

    Así que 'now' se convierte en una marca de tiempo en el momento del análisis.

  2. Declaraciones preparadas

    Bien, pero ¿qué significa con respecto a las funciones? Es fácil demostrar que una función se interpreta cada vez que la llamas:

    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)
    

    En este ejemplo 'now' se comporta como esperabas.

    ¿Cuál es la diferencia? Su función usa sentencias SQL y test() no. Veamos la documentación nuevamente (PL/ Almacenamiento en caché del plan pgSQL ):

    Y aquí (Preparar Declaración ):

    Por lo tanto 'now' se convirtió en una marca de tiempo cuando se analizó la declaración preparada. Demostremos esto creando una declaración preparada fuera de una función:

    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)
    

Eso es lo que pasó. 'now' se convirtió en una marca de tiempo una vez (cuando se analizó la declaración preparada) y now() fue llamado dos veces.