sql >> Database >  >> RDS >> PostgreSQL

Postgres nu() vs 'nu' in functie

Het is geen bug, het is een functie... Er zijn hier twee punten.

  1. Vervanging van 'nu'

    Laten we de documentatie eens bekijken (Datum /Tijdfuncties en operators ):

    Dus 'now' wordt tijdens het parseren omgezet in een tijdstempel.

  2. Voorbereide verklaringen

    Oké, maar wat betekent het met betrekking tot functies? Het is gemakkelijk om aan te tonen dat een functie elke keer dat u deze aanroept, wordt geïnterpreteerd:

    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 dit voorbeeld 'now' gedraagt ​​zich zoals je had verwacht.

    Wat is het verschil? Uw functie gebruikt SQL-instructies en test() niet. Laten we de documentatie opnieuw bekijken (PL/ pgSQL Plan Caching ):

    En hier (Prepare Statement ):

    Vandaar 'now' werd geconverteerd naar een tijdstempel toen de voorbereide instructie werd geparseerd. Laten we dit demonstreren door een voorbereide instructie buiten een functie te maken:

    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)
    

Dat is wat er gebeurde. 'now' eenmaal is geconverteerd naar een tijdstempel (toen de voorbereide instructie werd geparseerd), en now() werd twee keer gebeld.



  1. Leg MySQL uit, leg de wiskunde van het uitvoeringsplan uit, het verschil tussen twee plannen

  2. cx_Oracle:distutils.errors.DistutilsSetupError:kan Oracle include-bestanden niet vinden

  3. uniek toevoegen aan bestaande externe sleutel

  4. INSERT SELECT-query wanneer één kolom uniek is