Zaktualizuj sygnaturę czasową, gdy wiersz zostanie zaktualizowany w PostgreSQL

85

W MySQL możemy wykonać to, gdzie aktualizuje kolumnę za changetimestampkażdym razem, gdy zmienia się wiersz:

create table ab (
  id int, 
  changetimestamp timestamp 
    NOT NULL 
    default CURRENT_TIMESTAMP 
    on update CURRENT_TIMESTAMP 
);

Czy jest coś podobnego do powyższego w PostgreSQL?

bichonfrise74
źródło
afaik nie jest tak łatwy w PostgreSQL, gdzie potrzebujesz wyzwalacza: pointbeing.net/weblog/2008/03/…
Mechanical_meat
2
Warto zauważyć, że MySQL ma szereg "specjalnych zabiegów" dla timestampkolumn w zależności od wersji i ustawień, których (na szczęście!) Nie można odtworzyć w Postgresie. Podobnie jak zezwolenie 0na timestampkolumnę lub przekształcenie NULLw bieżący znacznik czasu na wejściu w niektórych konstelacjach. Zapoznaj się z instrukcją obsługi obu RDBMS, aby zdawać sobie sprawę z subtelnych różnic: MySQL i Postgres .
Erwin Brandstetter
1
@ErwinBrandstetter czy odpowiedź podana poniżej nadal jest najlepszą praktyką w zakresie automatycznego aktualizowania znaczników czasu w 2018 roku?
CommonSenseCode

Odpowiedzi:

125

Utwórz funkcję, która aktualizuje kolumnę changetimestamp tabeli w następujący sposób:

CREATE OR REPLACE FUNCTION update_changetimestamp_column()
RETURNS TRIGGER AS $$
BEGIN
   NEW.changetimestamp = now(); 
   RETURN NEW;
END;
$$ language 'plpgsql';

Utwórz wyzwalacz w tabeli, który wywoła funkcję update_changetimestamp_column () za każdym razem, gdy nastąpi aktualizacja:

    CREATE TRIGGER update_ab_changetimestamp BEFORE UPDATE
    ON ab FOR EACH ROW EXECUTE PROCEDURE 
    update_changetimestamp_column();
Charles Ma
źródło
2
Więc nie ma innego sposobu na zrobienie tego, co chcę, poza wyzwalaczem? Ponieważ chciałbym zaimplementować "przy aktualizacji timestamp" dla wszystkich moich tabel, prawdopodobnie 300+. Myślę, że tworzenie wyzwalaczy może powodować problemy z wydajnością.
bichonfrise74
5
O ile wiem, jest to standardowy sposób na zrobienie tego w postgresql. Kiedy piszesz „on update current_timestamp” w mysql, tworzy on wyzwalacz w tabeli w tle. Różnica polega na tym, że piszesz wyzwalacz tutaj ręcznie, zamiast pisać go za siebie.
Charles Ma
3
Praktycznie nie ma spadku wydajności - przynajmniej w każdej rozsądnej bazie danych.
5
Czy istnieje sposób nadania nazwy kolumny, która ma zostać zaktualizowana, jako parametr funkcji update_changetimestamp_column?
Antoan Milkov
7
@womble Prawdopodobnie bardzo przydatne byłoby opublikowanie tego przykładu. Jeśli uda mi się dynamicznie określić, którą kolumnę zaktualizować, napiszę to jako odpowiedź.
MirroredFate