Como atualizo automaticamente um carimbo de data e hora no PostgreSQL


132

Quero que o código seja capaz de atualizar automaticamente o carimbo de data / hora quando uma nova linha é inserida, como posso fazer no MySQL usando CURRENT_TIMESTAMP.

Como vou conseguir isso no PostgreSQL?

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

6
A propósito, seu tipo de dados timestampé definido pela especificação SQL como uma abreviação de TIMESTAMP WITHOUT TIME ZONE. Isso quase certamente não é o que você deseja, como explicado pelo especialista em postgres, David E. Wheeler . O outro tipo TIMESTAMP WITH TIME ZONEé provavelmente o que você deseja, usando as informações de deslocamento de fuso horário passadas para ajustar a data e hora para UTC (mas não armazenando as informações do fuso horário, apesar do nome do tipo).
— Basil Bourque

3
Depois de ter aprendido isso novamente, escrevi uma postagem de blog detalhada sobre o registro da data e hora da criação e modificação de uma linha usando padrão, função e gatilho. Inclui um exemplo completo de código SQL e PL / pgSQL para uso no Postgres.
— Basil Bourque

Respostas:


197

Para preencher a coluna durante a inserção, use um DEFAULTvalor:

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

Observe que o valor dessa coluna pode ser sobrescrito explicitamente, fornecendo um valor na INSERTinstrução Se você deseja impedir que você precise de um gatilho .

Você também precisará de um gatilho se precisar atualizar essa coluna sempre que a linha for atualizada (conforme mencionado por EJ Brennan )

Observe que o uso de palavras reservadas para nomes de colunas geralmente não é uma boa ideia. Você deve encontrar um nome diferente detimestamp


14
Esteja ciente de que o Postgres tem funções para informar (1) a hora do momento atual real, (2) a hora em que a instrução foi iniciada e (3) a hora em que a transação foi iniciada. O exemplo mostrado aqui é o início da transação atual. Você pode ou não querer isso em oposição às outras duas possibilidades.
— Basil Bourque

6
Bom ponto de bônus sobre evitar nomes que colidem com palavras reservadas. Observe que a especificação do SQL promete explicitamente nunca usar um sublinhado à direita como uma palavra reservada. Então você pode timestamptransformar timestamp_. Melhor ainda seria um nome mais descritivo como row_created_.
— Basil Bourque

A primeira metade não é exatamente o que o OP solicitou, embora a segunda metade se refira a outra resposta (o que é correto), mas ainda é enganosa. Isso não deve ser aceito como resposta.
— Eric Wang

1
Diz isso na documentação dos tipos do Postgres. O Varchar possui ciclos extras de CPU para verificar a restrição, o que não acontece no TEXT.
— Rahly

3
não com um único campo, mas nunca vi uma tabela útil com um único campo. Essa restrição é composta pelo número de campos. Lembro-me de alterar todos os varchars de uma tabela para textos e obtive uma melhoria de 15% na escrita. Além disso, pequenas penalidades de desempenho não são penalidades de desempenho "NÃO".
— Rahly

104

Você precisará escrever um gatilho de inserção e, possivelmente, um gatilho de atualização, se desejar que ele mude quando o registro for alterado. Este artigo explica muito bem:

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';

Aplique o gatilho assim:

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

2
Esta é a melhor resposta, IMO (embora um padrão seja suficiente para inserir).
— 22416

2
O que há de novo aqui?
— Naveen


Esta é uma solução mais completa que funcionaria com INSERTs iniciais, bem como com quaisquer UPDATEs subsequentes (bom para auditoria de dados). Concedido, o OP só pede o primeiro.
— Pavel Lechev

5
@ Naveen não muito, o que há de novo com você?
— Underyx 10/01

57

Atualizando carimbo de data e hora, apenas se os valores forem alterados

Com base no link do EJ e adicione uma declaração if neste link ( 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

Usar 'now ()' como valor padrão gera automaticamente registro de data e hora.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.