PostgreSQL에서 타임 스탬프를 자동으로 업데이트하는 방법


132

CURRENT_TIMESTAMP를 사용하여 MySQL에서 할 수있는 것처럼 새 행이 삽입되면 코드가 자동으로 타임 스탬프를 업데이트 할 수 있기를 바랍니다.

PostgreSQL에서 어떻게 이것을 달성 할 수 있습니까?

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

6
그건 그렇고, 귀하의 데이터 유형은 timestampSQL 사양에 의해 약어로 정의됩니다 TIMESTAMP WITHOUT TIME ZONE. Postgres 전문가 David E. Wheeler가 설명했듯이 거의 확실하지 않습니다 . 다른 유형 TIMESTAMP WITH TIME ZONE은 전달 된 시간대 오프셋 정보를 사용하여 날짜 시간을 UTC 로 조정 하지만 실제로는 유형 이름에도 불구하고 해당 시간대 정보를 저장하지는 않습니다.
Basil Bourque

3
이것을 다시 다시 배운 후, 기본, 함수 및 트리거를 사용하여 행 작성 및 수정 날짜 및 시간 기록에 관한 자세한 블로그 게시물을 작성했습니다. Postgres에서 사용하기위한 완전한 예제 SQL 및 PL / pgSQL 코드가 포함되어 있습니다.
Basil Bourque

답변:


197

삽입하는 동안 열을 채우려면 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 스펙은 명시 적으로 밑줄을 예약어로 사용하지 않을 것을 명시 적으로 약속합니다. 그래서 당신은 할 수 있습니다 timestamptimestamp_. 더 좋은 이름은 다음과 같습니다 row_created_.
Basil Bourque

후반은 다른 답변 (정확한)을 언급했지만 전반부는 OP가 전혀 요청한 것이 아니지만 여전히 오도합니다. 이것은 답변으로 받아 들여서는 안됩니다.
Eric Wang

1
유형에 대한 Postgres 설명서에서 그렇게 말합니다. Varchar에는 TEXT에서는 발생하지 않는 제약 조건을 확인하기위한 추가 CPU주기가 있습니다.
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 (데이터 감사에 적합)에서 작동하는보다 완벽한 솔루션입니다. 물론 OP는 전자에게만 요청합니다.
Pavel Lechev 2016 년

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.