Как автоматически обновить метку времени в PostgreSQL


134

Я хочу, чтобы код мог автоматически обновлять отметку времени при вставке новой строки, как я могу это сделать в MySQL, используя CURRENT_TIMESTAMP.

Как я смогу добиться этого в PostgreSQL?

CREATE TABLE users (
    id serial not null,
    firstname varchar(100),
    middlename varchar(100),
    lastname varchar(100),
    email varchar(200),
    timestamp timestamp
)

6
Кстати, ваш тип данных timestampопределяется спецификацией SQL как аббревиатура TIMESTAMP WITHOUT TIME ZONE. Как объяснил эксперт Postgres Дэвид Уиллер, это почти наверняка не то, что вам нужно . Другой тип, TIMESTAMP WITH TIME ZONEвероятно, то, что вы хотите, используя любую переданную информацию о смещении часового пояса для настройки даты и времени на UTC (но фактически не сохраняя информацию о часовом поясе, несмотря на имя типа).
— Basil Bourque

3
Узнав об этом еще раз, я написал подробное сообщение в блоге о регистрации даты и времени создания и изменения строки с использованием значений по умолчанию, функции и триггера. Включает полный пример кода SQL и PL / pgSQL для использования в Postgres.
— Basil Bourque

Ответы:


198

Чтобы заполнить столбец во время вставки, используйте DEFAULTзначение:

CREATE TABLE users (
  id serial not null,
  firstname varchar(100),
  middlename varchar(100),
  lastname varchar(100),
  email varchar(200),
  timestamp timestamp default current_timestamp
)

Обратите внимание, что значение этого столбца можно явно перезаписать, указав значение в INSERTоператоре. Если вы хотите предотвратить это, вам нужен триггер .

Вам также понадобится триггер, если вам нужно обновлять этот столбец всякий раз, когда обновляется строка (как упоминалось EJ Brennan )

Обратите внимание, что использование зарезервированных слов для имен столбцов обычно не является хорошей идеей. Вы должны найти другое имя, чемtimestamp


14
Имейте в виду, что в Postgres есть функции, которые сообщают вам (1) время фактического текущего момента, (2) время запуска оператора и (3) время начала транзакции. Показанный здесь пример - начало текущей транзакции. Вы можете захотеть или не захотеть этого в отличие от двух других возможностей.
— Basil Bourque

6
Хороший бонус в том, чтобы избегать имен, которые противоречат зарезервированным словам. Обратите внимание, что спецификация SQL явно обещает никогда не использовать завершающее подчеркивание в качестве зарезервированного слова. Так что вы можете превратиться timestampв timestamp_. Еще лучше было бы более описательное имя, например, как row_created_.
— Basil Bourque

Первая половина - это совсем не то, о чем спрашивал ОП, хотя вторая половина ссылалась на другой ответ (который правильный), но это все еще вводит в заблуждение. Это не следует принимать в качестве ответа.
— Эрик Ван

1
Об этом говорится в документации типов Postgres. У Varchar есть дополнительные циклы ЦП для проверки ограничения, чего не происходит в TEXT.
— Rahly

3
не с одним полем, но я никогда не видел полезной таблицы с одним полем. Это ограничение усугубляется количеством полей. Я помню, как изменил все varchar в таблице на текст и получил улучшение письма на 15%. Кроме того, небольшое снижение производительности не означает «НЕТ» ухудшения производительности.
— Rahly

104

Вам нужно будет написать триггер вставки и, возможно, триггер обновления, если вы хотите, чтобы он изменялся при изменении записи. Эта статья объясняет это довольно хорошо:

http://www.revsys.com/blog/2006/aug/04/automatically-updating-a-timestamp-column-in-postgresql/

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

Примените триггер следующим образом:

CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON customer FOR EACH ROW EXECUTE PROCEDURE  update_modified_column();

2
Это лучший ответ, IMO (хотя по умолчанию достаточно для вставки).
— kik

2
Что здесь нового?
— Naveen


Это более полное решение, которое будет работать как с начальными INSERT, так и с любыми последующими UPDATE (подходит для аудита данных). Конечно, ОП запрашивает только первое.
— Павел Лечев

5
@Naveen не много, что у тебя нового?
— Underyx,

57

Обновление метки времени, только если значения изменились

На основе ссылки EJ и добавьте оператор if из этой ссылки ( https://stackoverflow.com/a/3084254/1526023 )

CREATE OR REPLACE FUNCTION update_modified_column()
RETURNS TRIGGER AS $$
BEGIN
   IF row(NEW.*) IS DISTINCT FROM row(OLD.*) THEN
      NEW.modified = now(); 
      RETURN NEW;
   ELSE
      RETURN OLD;
   END IF;
END;
$$ language 'plpgsql';

9

Использование «сейчас ()» в качестве значения по умолчанию автоматически генерирует метку времени.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.