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
)
Aaron
fonte
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

um cavalo sem nome
fonte
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();
EJ Brennan
fonte
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';
Jim Yu
fonte
9

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

Parichay Mo
fonte