Наличие в MySQL 4.0 столбцов меток времени «Создано» и «Последнее обновление» - PullRequest
120 голосов
/ 06 ноября 2008

У меня есть следующая схема таблицы;

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 во время каждой транзакции?

Ответы [ 11 ]

114 голосов
/ 06 ноября 2008

Из документации MySQL 5.5 :

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

Изменения в MySQL 5.6.5 :

Ранее максимум один столбец TIMESTAMP на таблицу можно было автоматически инициализировать или обновить до текущей даты и времени. Это ограничение было снято. Любое определение столбца TIMESTAMP может содержать любую комбинацию предложений DEFAULT CURRENT_TIMESTAMP и ON UPDATE CURRENT_TIMESTAMP. Кроме того, эти предложения теперь можно использовать с определениями столбцов DATETIME. Для получения дополнительной информации см. Автоматическая инициализация и обновление для TIMESTAMP и DATETIME.

83 голосов
/ 30 апреля 2009

Есть хитрость , чтобы иметь обе отметки времени, но с небольшим ограничением.

Вы можете использовать только одно из определений в одной таблице. Создайте оба столбца отметок времени следующим образом:

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)  
27 голосов
/ 06 ноября 2008

Вы можете иметь их обоих, просто снимите флаг "CURRENT_TIMESTAMP" на созданном поле. Всякий раз, когда вы создаете новую запись в таблице, просто используйте «NOW ()» для значения.

Или.

Напротив, удалите флаг «ON UPDATE CURRENT_TIMESTAMP» и отправьте NOW () для этого поля. Этот способ на самом деле имеет больше смысла.

25 голосов
/ 24 июня 2011

Если вы решили, что 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

23 голосов
/ 07 мая 2013

Вот как вы можете иметь автоматические и гибкие поля 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 . Это не изменит дату последнего изменения.
21 голосов
/ 03 декабря 2013

Начиная с MySQL 5.6, его легко-peasy ... попробуйте:

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)
)
4 голосов
/ 09 февраля 2016
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() 
); 

источник: http://gusiev.com/2009/04/update-and-create-timestamps-with-mysql/

4 голосов
/ 14 ноября 2013

Эта проблема, похоже, была решена в 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 голосов
/ 05 мая 2018

я думаю, что это лучший запрос для 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'

1 голос
/ 14 июня 2018

Для mysql 5.7.21 я использую следующее и отлично работает:

CREATE TABLE Posts ( modified_at отметка времени NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, created_at отметка времени NOT NULL DEFAULT CURRENT_TIMESTAMP )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...