Почему в предложении DEFAULT может быть только один столбец TIMESTAMP с CURRENT_TIMESTAMP?
Почему в предложении DEFAULT или ON UPDATE может быть только один столбец TIMESTAMP с CURRENT_TIMESTAMP?
CREATE TABLE `foo` (
`ProductID` INT(10) UNSIGNED NOT NULL,
`AddedDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`UpdatedDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=INNODB;
Ошибка, которая приводит к:
Код ошибки: 1293
Неправильное определение таблицы; может быть только один столбец TIMESTAMP с CURRENT_TIMESTAMP в предложении DEFAULT или ON UPDATE
9 ответов
Это ограничение, которое было только из-за исторических, наследственных причин кода, было снято в последних версиях MySQL:
Изменения в MySQL 5.6.5 (2012-04-10, Milestone 8)
Ранее не более одного столбца TIMESTAMP на таблицу можно было автоматически инициализировать или обновить до текущей даты и времени. Это ограничение было снято. Любое определение столбца TIMESTAMP может содержать любую комбинацию предложений DEFAULT CURRENT_TIMESTAMP и ON UPDATE CURRENT_TIMESTAMP. Кроме того, эти предложения теперь можно использовать с определениями столбцов DATETIME. Для получения дополнительной информации см. Автоматическая инициализация и обновление для TIMESTAMP и DATETIME.
http://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-5.html
Я тоже удивился, что давным-давно. Я немного искал в своей истории, и я думаю, что этот пост: http://lists.mysql.com/internals/34919 представляет полуофициальную позицию MySQL (до вмешательства Oracle;))
Короче:
Это ограничение связано только с тем, как эта функция в настоящее время реализована на сервере, и нет никаких других причин ее существования.
Таким образом, их объяснение "потому что это реализовано так". Звучит не очень научно. Я думаю, все это происходит из какого-то старого кода. Это предлагается в ветке выше: "перенесено с того момента, когда было автоматически установлено / обновлено только первое поле отметки времени".
Ура!
Мы можем указать значение по умолчанию для отметки времени, чтобы избежать этой проблемы.
Этот пост дает подробный обходной путь: http://gusiev.com/2009/04/update-and-create-timestamps-with-mysql/
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() );
Обратите внимание, что во время "вставки" необходимо ввести пустые значения в оба столбца:
mysql> insert into test_table(stamp_created, stamp_updated) values(null, null); Query OK, 1 row affected (0.06 sec) mysql> select * from t5; +----+---------------------+---------------------+ | 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 заключается в том, чтобы самостоятельно обновлять дату создания (если она вам нужна) и заставлять MySQL беспокоиться о отметке времени update date ? update date : creation date
вот так:
CREATE TABLE tracked_data(
`data` TEXT,
`timestamp` TIMESTAMP,
`creation_date` TIMESTAMP
) ENGINE=INNODB;
При создании Вставьте NULL:
INSERT INTO tracked_data(`data`,`creation_date`) VALUES ('creation..',NULL);
Значения NULL для метки времени по умолчанию интерпретируются как CURRENT_TIMESTAMP.
В MySQL первый столбец TIMESTAMP таблицы получает оба DEFAULT CURRENT_TIMESTAMP
а также ON UPDATE CURRENT_TIMESTAMP
атрибут, если для него не задано никаких атрибутов. Вот почему столбец TIMESTAMP с атрибутами должен стоять первым, иначе вы получите сообщение об ошибке, описанное в этой теме.
- Изменить типы данных столбцов на дату и время
- Установить триггер
Такие как:
DROP TRIGGER IF EXISTS `update_tablename_trigger`;
DELIMITER //
CREATE TRIGGER `update_tablename_trigger` BEFORE UPDATE ON `tablename`
FOR EACH ROW SET NEW.`column_name` = NOW()
//
DELIMITER ;
Сочетание разных ответов:
В MySQL 5.5 DEFAULT CURRENT_TIMESTAMP
а также ON UPDATE CURRENT_TIMESTAMP
не может быть добавлено DATETIME
но только на TIMESTAMP
,
Правила:
1) максимум один TIMESTAMP
столбец на таблицу может быть автоматически (или вручную [Моё дополнение]) инициализирован или обновлен до текущей даты и времени. (MySQL Docs).
Так что только один TIMESTAMP
могу иметь CURRENT_TIMESTAMP
в DEFAULT
или же ON UPDATE
пункт
2) первый NOT NULL
TIMESTAMP
столбец без явного DEFAULT
значение как created_date timestamp default '0000-00-00 00:00:00'
будет неявно дано DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
и, следовательно, последующее TIMESTAMP
столбцы не могут быть заданы CURRENT_TIMESTAMP
на DEFAULT
или же ON UPDATE
пункт
CREATE TABLE `address` (
`id` int(9) NOT NULL AUTO_INCREMENT,
`village` int(11) DEFAULT NULL,
`created_date` timestamp default '0000-00-00 00:00:00',
-- Since explicit DEFAULT value that is not CURRENT_TIMESTAMP is assigned for a NOT NULL column,
-- implicit DEFAULT CURRENT_TIMESTAMP is avoided.
-- So it allows us to set ON UPDATE CURRENT_TIMESTAMP on 'updated_date' column.
-- How does setting DEFAULT to '0000-00-00 00:00:00' instead of CURRENT_TIMESTAMP help?
-- It is just a temporary value.
-- On INSERT of explicit NULL into the column inserts current timestamp.
-- `created_date` timestamp not null default '0000-00-00 00:00:00', // same as above
-- `created_date` timestamp null default '0000-00-00 00:00:00',
-- inserting 'null' explicitly in INSERT statement inserts null (Ignoring the column inserts the default value)!
-- Remember we need current timestamp on insert of 'null'. So this won't work.
-- `created_date` timestamp null , // always inserts null. Equally useless as above.
-- `created_date` timestamp default 0, // alternative to '0000-00-00 00:00:00'
-- `created_date` timestamp,
-- first 'not null' timestamp column without 'default' value.
-- So implicitly adds DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP.
-- Hence cannot add 'ON UPDATE CURRENT_TIMESTAMP' on 'updated_date' column.
`updated_date` timestamp null on update current_timestamp,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=132 DEFAULT CHARSET=utf8;
INSERT INTO address (village,created_date) VALUES (100,null);
mysql> select * from address;
+-----+---------+---------------------+--------------+
| id | village | created_date | updated_date |
+-----+---------+---------------------+--------------+
| 132 | 100 | 2017-02-18 04:04:00 | NULL |
+-----+---------+---------------------+--------------+
1 row in set (0.00 sec)
UPDATE address SET village=101 WHERE village=100;
mysql> select * from address;
+-----+---------+---------------------+---------------------+
| id | village | created_date | updated_date |
+-----+---------+---------------------+---------------------+
| 132 | 101 | 2017-02-18 04:04:00 | 2017-02-18 04:06:14 |
+-----+---------+---------------------+---------------------+
1 row in set (0.00 sec)
Другой вариант (но updated_date
это первый столбец):
CREATE TABLE `address` (
`id` int(9) NOT NULL AUTO_INCREMENT,
`village` int(11) DEFAULT NULL,
`updated_date` timestamp null on update current_timestamp,
`created_date` timestamp not null ,
-- implicit default is '0000-00-00 00:00:00' from 2nd timestamp onwards
-- `created_date` timestamp not null default '0000-00-00 00:00:00'
-- `created_date` timestamp
-- `created_date` timestamp default '0000-00-00 00:00:00'
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=132 DEFAULT CHARSET=utf8;
Можно исправить это, поместив его в поле updatedDate и запустив триггер, который обновляет поле AddedDate со значением Обновлено Date, только если AddedDate имеет значение null.
Это ограничение в версии MYSQL 5.5. Вам нужно обновить версию до 5.6.
Error
Я получаю эту ошибку при добавлении таблицы в MYSQL
Неправильное определение таблицы; может быть только один столбец TIMESTAMP с CURRENT_TIMESTAMP в предложении DEFAULT или ON UPDATE Мой новый MYSQL
таблица выглядит примерно так.
создать таблицу имя_таблицы (col1 int(5), первичный ключ auto_increment, col2 varchar(300), col3 varchar(500), col4 int(3), col5 tinyint(2), временная метка col6 по умолчанию current_timestamp, временная метка col7 по умолчанию current_timestamp при обновлении current_timestamp, col8 tinyint(1) по умолчанию 0, col9 tinyint(1) по умолчанию 1);
После некоторого времени чтения об изменениях в различных версиях MYSQL и некоторых поисках в Google. Я обнаружил, что в MYSQL версии 5.6 были внесены некоторые изменения по сравнению с версией 5.5.
Эта статья поможет вам решить проблему. http://www.oyewiki.com/MYSQL/Incorrect-table-definition-there-can-be-only-one-timestamp-column
Попробуй это:
CREATE TABLE `test_table` (
`id` INT( 10 ) NOT NULL,
`created_at` TIMESTAMP NOT NULL DEFAULT 0,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE = INNODB;