MySQL 4.0에서 생성 및 마지막 업데이트 타임 스탬프 열 모두


127

다음과 같은 테이블 스키마가 있습니다.

CREATE TABLE `db1`.`sms_queue` (
  `Id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  `Message` VARCHAR(160) NOT NULL DEFAULT 'Unknown Message Error',
  `CurrentState` VARCHAR(10) NOT NULL DEFAULT 'None',
  `Phone` VARCHAR(14) DEFAULT NULL,
  `Created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `LastUpdated` TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP,
  `TriesLeft` tinyint NOT NULL DEFAULT 3,
  PRIMARY KEY (`Id`)
)
ENGINE = InnoDB;

다음 오류와 함께 실패합니다.

ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause.

내 질문은, 그 두 분야를 모두 가질 수 있습니까? 또는 각 트랜잭션 중에 LastUpdated 필드를 수동으로 설정해야합니까?


@Xenph Yan, "Accepted"답변을 현재 잘못된 답변에서 올바른 답변으로 변경 하시겠습니까? 이것은 받아 들여지고, 틀린 대답으로 약 15 분 동안 무슨 일이 일어나고 있는지 알아 내려고했지만 ...
Bruno Reis

1
@BrunoReis 완료되었습니다.
Xenph Yan

답변:


128

보내는 사람 의 MySQL 5.5 문서 :

테이블에서 하나의 TIMESTAMP 열은 현재 시간 소인을 열 초기화의 기본값, 자동 업데이트 값 또는 둘 다로 가질 수 있습니다. 현재 타임 스탬프를 한 열의 기본값으로 설정하고 다른 열의 자동 업데이트 값으로 설정할 수 없습니다.

MySQL 5.6.5의 변경 사항 :

이전에는 테이블 당 최대 하나의 TIMESTAMP 열을 자동으로 초기화하거나 현재 날짜 및 시간으로 업데이트 할 수있었습니다. 이 제한이 해제되었습니다. TIMESTAMP 컬럼 정의는 DEFAULT CURRENT_TIMESTAMP 및 ON UPDATE CURRENT_TIMESTAMP 절의 조합을 가질 수 있습니다. 또한이 절은 DATETIME 열 정의와 함께 사용할 수 있습니다. 자세한 내용은 TIMESTAMP 및 DATETIME 자동 초기화 및 업데이트를 참조하십시오.


변경되었습니다 (적어도 MySQL 5.0에서는). : 문서를 참조하십시오 dev.mysql.com/doc/refman/5.0/en/timestamp.html
SimonSimCity

@SimonSimCity에 대한 반박 : 5.0에 대한 문서는 위와 똑같은 것을 말합니다.
davemyron

5
@RobertGamble 더 흥미로운 질문은 왜 그들이 매우 일반적으로 요청 / 필요한 기능을 수행 할 수있는 방법을 제공하지 않았는 가라고 생각합니다.
Ray

22
이것은 MySQL의 경우 약간 임의적 인 것처럼 보입니다. 아무도 이것이 왜 그런지 설명 할 수 있습니까 ?
humble_coder

12
정말 오래된 의견이지만, 마침내 바뀌 었습니다. Changes in MySQL 5.6.5 (2012-04-10, Milestone 8) Previously, at most one TIMESTAMP column per table could be automatically initialized or updated to the current date and time. This restriction has been lifted. Any TIMESTAMP column definition can have any combination of DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses. In addition, these clauses now can be used with DATETIME column definitions. For more information, see Automatic Initialization and Updating for TIMESTAMP and DATETIME.
Mauricio Vargas

83

두 개의 타임 스탬프를 모두 갖는 트릭 이 있지만 약간의 제한이 있습니다.

한 테이블에서 하나의 정의 만 사용할 수 있습니다. 다음과 같이 두 타임 스탬프 열을 만듭니다.

create table test_table( 
  id integer not null auto_increment primary key, 
  stamp_created timestamp default '0000-00-00 00:00:00', 
  stamp_updated timestamp default now() on update now() 
); 

다음 null동안 두 열을 모두 입력해야합니다 insert.

mysql> insert into test_table(stamp_created, stamp_updated) values(null, null); 
Query OK, 1 row affected (0.06 sec)

mysql> select * from test_table; 
+----+---------------------+---------------------+ 
| id | stamp_created       | stamp_updated       |
+----+---------------------+---------------------+
|  2 | 2009-04-30 09:44:35 | 2009-04-30 09:44:35 |
+----+---------------------+---------------------+
2 rows in set (0.00 sec)  

mysql> update test_table set id = 3 where id = 2; 
Query OK, 1 row affected (0.05 sec) Rows matched: 1  Changed: 1  Warnings: 0  

mysql> select * from test_table;
+----+---------------------+---------------------+
| id | stamp_created       | stamp_updated       | 
+----+---------------------+---------------------+ 
|  3 | 2009-04-30 09:44:35 | 2009-04-30 09:46:59 | 
+----+---------------------+---------------------+ 
2 rows in set (0.00 sec)  

다음은 그 기능을 설명은 MySQL-문서에서 링크는 다음과 같습니다 dev.mysql.com/doc/refman/5.0/en/timestamp.html
SimonSimCity

6
첫 번째 코드 상자는 수동으로 입력했을 때 완벽하게 작동했습니다. 감사! 베이컨을 구할 때이 답변을 찬성하기에 충분한 '카르마'가 있었으면 좋겠습니다. mmmmm 저장 베이컨.
amatusko 2016 년

stamp_created NOT NULL로 설정되어 있는지 확인해야 합니다. MySQL은 NULL을 현재 타임 스탬프로 자동 대체합니다.
Valentin Despa

'ZERO'값을 사용하는 대신 stamp_created필드를 다음과 같이 작성하지 않겠 stamp_created timestamp default now()습니까?
Sebastian Scholle

28

생성 된 필드에서 "CURRENT_TIMESTAMP"플래그를 제거하면됩니다. 테이블에서 새 레코드를 작성할 때마다 값에 "NOW ()"를 사용하십시오.

또는.

반대로 'ON UPDATE CURRENT_TIMESTAMP'플래그를 제거하고 해당 필드에 NOW ()를 보내십시오. 그렇게하면 실제로 더 의미가 있습니다.


2
이것이 유일한 방법입니까? 데이터베이스가 모든 세부 사항을 보도록 할 수 없습니까?
Xenph Yan

2
MySql 매뉴얼에 따르면 CURRENT_TIMESTAMP는 NOW ()의 동의어이므로 이것이 작동하지 않을 것이라고 생각합니다.
tvanfosson

CURRENT_TIMESTAMP는 하나의 필드에만 예약 된 플래그 일뿐입니다. 어느 쪽이든, 레코드를 추가 할 때 해당 필드에 어떤 값이 있는지에 관계없이 해당 플래그가 있으면 항상 현재 시간 소인이되어 이름이됩니다.
Stephen Walcher

1
@tvanfosson : 쿼리에서 'NOW ()'를 사용하면 현재 시간이 데이터베이스로 전달됩니다. 그 가치는 실제로 언어, 엔진 및 아마도 모르는 백 가지에 달려 있습니다. 내가 언급 한 플래그는 레코드가 작성 될 때 시간이 해당 필드에 추가되도록 설정합니다.
Stephen Walcher

2
나는 다른 코드 가이 테이블을 만질 수 있기 때문에 NOW () 삽입 방법을 사용했으며 사람들을 올바르게 업데이트한다고 신뢰하지 않습니다. :)
Xenph Yan

26

MySQL이 타임 스탬프 업데이트를 처리하도록 결정한 경우 삽입시 필드를 업데이트하는 트리거를 설정할 수 있습니다.

CREATE TRIGGER <trigger_name> BEFORE INSERT ON <table_name> FOR EACH ROW SET NEW.<timestamp_field> = CURRENT_TIMESTAMP;

MySQL 참조 : http://dev.mysql.com/doc/refman/5.0/en/triggers.html


이것이 내가 찾던 것이 좋았습니다. 쿼리에 NOW ()를 추가 한 사람들에게 의존하고 싶지 않습니다!
Bot

실제로 새로운를 삽입 한 후 수행하고 설정하는 것이 좋습니다 것 <timestamp_field> = 새 <timestamp_field 실제로 기본 CURRENT_TIMESTAMP이있어> 두 필드가 consistant입니다 이런 식으로..
KacieHouser

@KacieHouser 트리거 이후에는 새 행을 업데이트 할 수 없습니다.
Thomas

23

트리거를 사용하여 자동 및 유연한 createDate / lastModified 필드를 만드는 방법은 다음과 같습니다.

먼저 다음과 같이 정의하십시오.

CREATE TABLE `entity` (
  `entityid` int(11) NOT NULL AUTO_INCREMENT,
  `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `lastModified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `name` varchar(255) DEFAULT NULL,
  `comment` text,
  PRIMARY KEY (`entityid`),
)

그런 다음이 트리거를 추가하십시오.

DELIMITER ;;
CREATE trigger entityinsert BEFORE INSERT ON entity FOR EACH ROW BEGIN SET NEW.createDate=IF(ISNULL(NEW.createDate) OR NEW.createDate='0000-00-00 00:00:00', CURRENT_TIMESTAMP, IF(NEW.createDate<CURRENT_TIMESTAMP, NEW.createDate, CURRENT_TIMESTAMP));SET NEW.lastModified=NEW.createDate; END;;
DELIMITER ;
CREATE trigger entityupdate BEFORE UPDATE ON entity FOR EACH ROW SET NEW.lastModified=IF(NEW.lastModified<OLD.lastModified, OLD.lastModified, CURRENT_TIMESTAMP);
  • createDate 또는 lastModified를 지정하지 않고 삽입 하면 동일하고 현재 타임 스탬프로 설정됩니다.
  • 당신이 경우 업데이트 createDate 또는과 lastModified를 지정하지 않고 그들을의과 lastModified는 현재 타임 스탬프로 설정됩니다.

그러나 여기 좋은 부분이 있습니다.

  • 삽입 하면 현재 타임 스탬프보다 오래된 createDate를 지정하여 이전 시간의 가져 오기가 제대로 작동하도록 할 수 있습니다 (lastModified는 createDate와 동일 함).
  • 당신이 경우 업데이트 , 당신은 지정할 수 이전 값보다 오래된 LASTMODIFIED 당신이 코멘트에 오타를 수정 화장 변경 (하고있는 경우 항목을 업데이트 할 수 있도록 ( '0000-00-00 00:00:00'잘 작동합니다) ) 및 이전 lastModified 날짜 를 유지 하려고 합니다. lastModified 날짜는 수정되지 않습니다.

21

MySQL 5.6부터는 쉬운 ... 시도해보십시오 :

create table tweet ( 
    id integer not null auto_increment primary key, 
    stamp_created timestamp default now(), 
    stamp_updated timestamp default now() on update now(),
    message varchar(163)
)

아마도 훌륭한 솔루션 내가 찾고있는 것은 트리거없이 시간 문제를 생성 및 업데이트
matinict

이 작은 성가심이 해결되는 데 오랜 시간이 걸렸다는 것을 믿을 수 없습니다. 나는 그들이 이것을 고쳤다는 것을 몰랐고 2018 년입니다 ... 감사합니다.
hsanders

4

이 문제는 MySQL 5.6에서 해결 된 것 같습니다. 나는 MySQL 5.5까지 이것을 보았다. 다음은 예제 코드입니다.

DROP TABLE IF EXISTS `provider_org_group` ;
CREATE TABLE IF NOT EXISTS `provider_org_group` (
  `id` INT NOT NULL,
  `name` VARCHAR(100) NOT NULL,
  `type` VARCHAR(100) NULL,
  `inserted` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `insert_src_ver_id` INT NULL,
  `updated` TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP,
  `update_src_ver_id` INT NULL,
  `version` INT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `id_UNIQUE` (`id` ASC),
  UNIQUE INDEX `name_UNIQUE` (`name` ASC))
ENGINE = InnoDB;

MySQL 5.5에서 이것을 실행하면 다음이 제공됩니다.

ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause

MySQL 5.6에서 이것을 실행

0 row(s) affected   0.093 sec


2

mysql 5.7.21의 경우 다음을 사용하고 정상적으로 작동합니다.

CREATE TABLE Posts( modified_at업데이트 CURRENT_TIMESTAMP에 created_at타임 스탬프 NOT NULL DEFAULT CURRENT_TIMESTAMP , 타임 스탬프 NOT NULL DEFAULT CURRENT_TIMESTAMP)


1

stamp_created 및 stamp_updated에 대한 더 나은 쿼리라고 생각합니다.

CREATE TABLE test_table( 
    id integer not null auto_increment primary key, 
    stamp_created TIMESTAMP DEFAULT now(), 
    stamp_updated TIMESTAMP DEFAULT '0000-00-00 00:00:00' ON UPDATE now() 
); 

레코드가 만들 때 때문에, stamp_created에 의해 채워 져야 now()하고 stamp_updated의해 채워 져야'0000-00-00 00:00:00'


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