Как установить значение по умолчанию для столбца MySQL Datetime?

777

Как установить значение по умолчанию для столбца MySQL Datetime?

В SQL Server это getdate(). Что такое эквивалент для MySQL? Я использую MySQL 5.x, если это фактор.

  • 3
    Я использую CURRENT_TIMESTAMP в моей таблице MySQL (не в запросе), может быть, это тоже может быть полезным.
  • 15
    Эта функция была добавлена в MySQL 5.6.5. Надеюсь, это кому-нибудь поможет. optimize-this.blogspot.co.uk/2012/04/...
Показать ещё 1 комментарий
Теги:
datetime

24 ответа

767
Лучший ответ

ВАЖНЫЙ РЕДАКТ: теперь это можно достичь с помощью полей DATETIME, начиная с MySQL 5.6.5, взгляните на другой пост ниже...

Предыдущие версии не могут сделать это с DATETIME...

Но вы можете сделать это с помощью TIMESTAMP:

mysql> create table test (str varchar(32), ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.00 sec)

mysql> desc test;
+-------+-------------+------+-----+-------------------+-------+
| Field | Type        | Null | Key | Default           | Extra |
+-------+-------------+------+-----+-------------------+-------+
| str   | varchar(32) | YES  |     | NULL              |       | 
| ts    | timestamp   | NO   |     | CURRENT_TIMESTAMP |       | 
+-------+-------------+------+-----+-------------------+-------+
2 rows in set (0.00 sec)

mysql> insert into test (str) values ("demo");
Query OK, 1 row affected (0.00 sec)

mysql> select * from test;
+------+---------------------+
| str  | ts                  |
+------+---------------------+
| demo | 2008-10-03 22:59:52 | 
+------+---------------------+
1 row in set (0.00 sec)

mysql>

** CAVEAT: Если вы по умолчанию задаете столбец с CURRENT_TIMESTAMP ON, вам нужно ВСЕГДА указать значение для этого столбца, иначе значение автоматически будет самовосстанавливаться до "now()" при обновлении. Это означает, что если вы не хотите, чтобы значение изменялось, ваш оператор UPDATE должен содержать "[имя вашего столбца] = [ваше имя столбца]" (или какое-то другое значение), или значение станет "now()". Странно, но верно. Надеюсь, это поможет. Я использую 5.5.56-MariaDB **

  • 378
    важно отметить, что у datetime есть диапазон 1000-9999, но диапазон для метки времени - только 1970-2038 . это может быть проблемой, если ваша система должна хранить даты рождения или вам нужно что-то вроде плана платежей для 30-летней ипотеки. dev.mysql.com/doc/refman/5.0/en/datetime.html
  • 12
    Будьте осторожны с меткой времени, так как она автоматически обновляется магическим образом ... см. Следующий ответ stackoverflow.com/a/1483959/233906
Показать ещё 3 комментария
526

В версии 5.6.5 можно установить значение по умолчанию в столбце datetime и даже создать столбец, который будет обновляться при обновлении строки. Определение типа:

CREATE TABLE foo (
    `creation_time`     DATETIME DEFAULT CURRENT_TIMESTAMP,
    `modification_time` DATETIME ON UPDATE CURRENT_TIMESTAMP
)

Ссылка: http://optimize-this.blogspot.com/2012/04/datetime-default-now-finally-available.html

  • 2
    Неверное значение по умолчанию для «menu_creation_time»
  • 1
    @FernandoTrindade Вам нужна MySQL версии 5.6.5 или новее. Вы можете увидеть это работает здесь: sqlfiddle.com/#!9/dd2be
Показать ещё 5 комментариев
136

MySQL (до версии 5.6.5) не позволяет использовать функции для значений по умолчанию DateTime. TIMESTAMP не подходит из-за его нечетного поведения и не рекомендуется использовать в качестве входных данных. (См. Тип данных MySQL по умолчанию.)

Тем не менее, вы можете выполнить этот создав триггер.

У меня есть таблица с полем DateCreated типа DateTime. Я создал триггер на этой таблице "Before Insert" и "SET NEW.DateCreated=NOW()", и он отлично работает.

Надеюсь, это поможет кому-то.

  • 20
    CREATE TRIGGER trigger_foo_SetCreatedAt ПЕРЕД ВСТАВКОЙ НА foo ДЛЯ КАЖДОЙ СТРОКИ УСТАНОВЛЕНА NEW.created_at = UTC_TIMESTAMP ();
  • 4
    Вы, вероятно, лучше использовать временную метку, чем триггер для будущего здравомыслия (обслуживания). Это слишком тривиальный вариант использования триггера, хотя это решение.
Показать ещё 1 комментарий
127

Для меня триггерный подход работал лучше всего, но я нашел уловку с подходом. Рассмотрим основной триггер, чтобы установить поле даты в текущее время на вставке:

CREATE TRIGGER myTable_OnInsert BEFORE INSERT ON `tblMyTable`
    FOR EACH ROW SET NEW.dateAdded = NOW();

Обычно это замечательно, но скажите, что вы хотите установить поле вручную с помощью инструкции INSERT, например:

INSERT INTO tblMyTable(name, dateAdded) VALUES('Alice', '2010-01-03 04:30:43');

Что происходит, так это то, что триггер сразу перезаписывает ваше предоставленное значение для поля, и поэтому единственный способ установить не текущее время - это продолжение инструкции UPDATE - yuck! Чтобы переопределить это поведение при предоставлении значения, попробуйте этот слегка модифицированный триггер с помощью оператора IFNULL:

CREATE TRIGGER myTable_OnInsert BEFORE INSERT ON `tblMyTable`
    FOR EACH ROW SET NEW.dateAdded = IFNULL(NEW.dateAdded, NOW());

Это дает лучшее из обоих миров: вы можете указать значение для своего столбца даты, и это займет, и в противном случае оно будет по умолчанию текущим временем. Это все еще гетто относительно чего-то чистого, такого как DEFAULT GETDATE() в определении таблицы, но мы приближаемся!

  • 5
    +1 за подтверждение предостережения с перезаписью явных пользовательских значений при вставке.
  • 2
    Я лично думаю, что это лучший путь. У TIMESTAMP действительно странное поведение, и я бы никогда не написал код с ограничением в 2038 лет.
Показать ещё 3 комментария
24

Мне удалось решить это, используя этот оператор alter в моей таблице, в котором было два поля datetime.

ALTER TABLE `test_table`
  CHANGE COLUMN `created_dt` `created_dt` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
  CHANGE COLUMN `updated_dt` `updated_dt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

Это работает так, как вы ожидали, что функция now() будет работать. Вставка нулей или игнорирование полей created_dt и updated_dt приводит к отличному значению метки времени в обоих полях. Любое обновление строки изменяет update_dt. Если вы вставляете записи через браузер запросов MySQL, вам нужен еще один шаг, триггер для обработки created_dt с новой меткой времени.

CREATE TRIGGER trig_test_table_insert BEFORE INSERT ON `test_table`
    FOR EACH ROW SET NEW.created_dt = NOW();

Триггер может быть любым, что вы хотите Мне просто нравится соглашение об именах [trig] _ [my_table_name] _ [insert]

  • 0
    Я хотел сказать, что если вы вставляете записи через браузер запросов MySQL вручную через сетку без оператора insert (), то необходим триггер. Если вы всегда используете оператор вставки, триггер совершенно не нужен.
  • 0
    Упс! Я имел в виду, что триггер (имя) может быть любым, каким вы хотите, потому что имя триггера не влияет на функциональность вообще. Большинство людей знают это, но некоторые люди, плохо знакомые с MySQL, могут не знать ...
Показать ещё 2 комментария
21

Вы можете использовать триггеры для создания этого типа вещей.

CREATE TABLE `MyTable` (
`MyTable_ID`  int UNSIGNED NOT NULL AUTO_INCREMENT ,
`MyData`  varchar(10) NOT NULL ,
`CreationDate`  datetime NULL ,
`UpdateDate`  datetime NULL ,
PRIMARY KEY (`MyTable_ID`)
)
;

CREATE TRIGGER `MyTable_INSERT` BEFORE INSERT ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the creation date
    SET new.CreationDate = now();

        -- Set the udpate date
    Set new.UpdateDate = now();
END;

CREATE TRIGGER `MyTable_UPDATE` BEFORE UPDATE ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the udpate date
    Set new.UpdateDate = now();
END;
14

Для всех, кто потерял сердце, пытаясь установить значение DATETIME по умолчанию MySQL, я точно знаю, как вы себя чувствуете. Так вот:

ALTER TABLE  `table_name` CHANGE `column_name` DATETIME NOT NULL DEFAULT 0

Внимательно наблюдайте, что я не добавил одиночные кавычки/двойные кавычки вокруг 0

Я буквально прыгаю после решения этой проблемы: D

  • 7
    Не вставляет не текущее время. Будет вставлено «0000-00-00 00:00:00».
  • 8
    Я не сказал, что устанавливает текущее время. Многие пользователи были / пытаются установить нулевое значение по умолчанию, но это просто не работает. Нам нужно исключить цитаты. Поскольку этот вывод вызвал много времени и разочарований, я подумал поделиться им с сообществом. Люди, подобные вам, несут ответственность за то, что пользователи теряют интерес к обмену полезной информацией с другими людьми. Я серьезно не вижу причин, чтобы получить -1! Без разницы.
Показать ещё 3 комментария
12

MySQL 5.6 исправил эту проблему.

ALTER TABLE mytable CHANGE mydate datetime NOT NULL DEFAULT 'CURRENT_TIMESTAMP'
12

Это действительно страшные новости. вот длинный ожидающий запрос об ошибке/функции для этого. это обсуждение также говорит об ограничениях типа данных временной метки.

Я серьезно задаюсь вопросом, в чем проблема с реализацией этой вещи.

8

Если вы уже создали таблицу, вы можете использовать

Чтобы изменить значение по умолчанию на текущее время

ALTER TABLE <TABLE_NAME> 
CHANGE COLUMN <COLUMN_NAME> <COLUMN_NAME> DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;

Чтобы изменить значение по умолчанию до '2015-05-11 13:01:01'

ALTER TABLE <TABLE_NAME> 
CHANGE COLUMN <COLUMN_NAME> <COLUMN_NAME> DATETIME NOT NULL DEFAULT '2015-05-11 13:01:01';
7

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

http://dev.mysql.com/doc/refman/5.0/en/datetime.html

"Тип данных TIMESTAMP имеет диапазон '1970-01-01 00:00:01' UTC to ' 2038-01-19 03:14:07' UTC. свойства, в зависимости от версии MySQL и режима SQL, на котором запущен сервер. Эти свойства описаны далее в этом разделе."

Таким образом, это, очевидно, сломает ваше программное обеспечение примерно через 28 лет.

Я считаю, что единственным решением на стороне базы данных является использование триггеров, как упомянуто в других ответах.

  • 2
    Что если MySQL будет обновлен через 20 лет и это ограничение будет снято? Я не уверен, что это возможно, но только мысль.
6

Я запускаю MySql Server 5.7.11 и это предложение:

ALTER TABLE table_name CHANGE date_column datetime NOT NULL DEFAULT '0000-00-00 00:00:00'

не работает. Но следующее:

ALTER TABLE table_name CHANGE date_column datetime NOT NULL DEFAULT '1000-01-01 00:00:00'

просто работает.

Как побочный элемент, он упоминается в документах mysql:

Тип DATE используется для значений с частью даты, но без временной части. MySQL извлекает и отображает значения DATE в формате "YYYY-MM-DD". Поддерживаемый диапазон - от "1000-01-01" до "9999-12-31".

даже если они также говорят:

Недопустимые значения DATE, DATETIME или TIMESTAMP преобразуются в нулевое значение соответствующего типа ('0000-00-00' или '0000-00-00 00:00:00').

6

При определении многострочных триггеров нужно изменить разделитель, поскольку точка с запятой будет приниматься компилятором MySQL в конце триггера и генерировать ошибку. например.

DELIMITER //
CREATE TRIGGER `MyTable_UPDATE` BEFORE UPDATE ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the udpate date
    Set new.UpdateDate = now();
END//
DELIMITER ;
6

Вы можете использовать now() для установки значения столбца datetime, но имейте в виду, что вы не можете использовать это как значение по умолчанию.

  • 4
    правда. Я только что попытался использовать сейчас и получил ошибку «Код ошибки: 1067. Неверное значение по умолчанию.». так какой ответ? ;-)
  • 0
    Это лучшее решение для компрометации версий MySQL 5.5 и 5.6. Для версии 5.5 предварительно определите значение NOW() и используйте его позже для вставки. Для версии 5.6 просто установите NOW() в качестве значения по умолчанию.
5

Пока вы не можете сделать это с помощью DATETIME в определении по умолчанию, вы можете просто включить оператор select в свой оператор insert так:

INSERT INTO Yourtable (Field1, YourDateField) VALUES('val1', (select now()))

Обратите внимание на отсутствие кавычек в таблице.

Для MySQL 5.5

  • 10
    сейчас () вместо (выберите сейчас ()) будет достаточно
4

Вот как это сделать в MySQL 5.1:

ALTER TABLE `table_name` CHANGE `column_name` `column_name` 
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

Я не знаю, почему вам нужно дважды вводить имя столбца.

  • 5
    CHANGE также для переименования поля. Имя первого столбца - «старый», имя второго столбца - «новый». Это выглядит излишним, если вы не меняете имя поля. Если это слишком эстетично, попробуйте MODIFY.
3

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

2

Используйте следующий код

DELIMITER $$

    CREATE TRIGGER bu_table1_each BEFORE UPDATE ON table1 FOR EACH ROW
    BEGIN
      SET new.datefield = NOW();
    END $$

    DELIMITER ;
2
CREATE TABLE `testtable` (
    `id` INT(10) NULL DEFAULT NULL,
    `colname` DATETIME NULL DEFAULT '1999-12-12 12:12:12'
)

В приведенном выше запросе для создания "testtable" я использовал "1999-12-12 12:12:12" в качестве значения по умолчанию для столбца DATETIME colname

1

Я думаю, что это просто в mysql, поскольку mysql встроенная функция, называемая now(), которая дает текущее время (время этой вставки).

Таким образом, ваш запрос должен выглядеть аналогично

CREATE TABLE defaultforTime(
    'creation_time'     DATETIME DEFAULT CURRENT_TIMESTAMP,
    'modification_time' DATETIME default now()
);

Спасибо.

0

Это мой пример триггера:

/************ ROLE ************/
drop table if exists `role`;
create table `role` (
    `id_role` bigint(20) unsigned not null auto_increment,
    `date_created` datetime,
    `date_deleted` datetime,
    `name` varchar(35) not null,
    `description` text,
    primary key (`id_role`)
) comment='';

drop trigger if exists `role_date_created`;
create trigger `role_date_created` before insert
    on `role`
    for each row 
    set new.`date_created` = now();
0

Возьмем, например, если у меня была таблица с именем "site" с столбцом created_at и update_at, которые были и DATETIME, и теперь нужно значение по умолчанию, для этого я мог бы выполнить следующий sql.

ALTER TABLE `site` CHANGE `created_at` `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

ALTER TABLE `site` CHANGE `created_at` `created_at` DATETIME  NULL DEFAULT NULL;

ALTER TABLE `site` CHANGE `updated_at` `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

ALTER TABLE `site` CHANGE `updated_at` `updated_at` DATETIME NULL DEFAULT  NULL;

Последовательность операторов важна, потому что таблица не может иметь два столбца типа TIMESTAMP со значениями по умолчанию CUREENT TIMESTAMP

0

Если вы пытаетесь установить значение по умолчанию как NOW(), MySQL поддерживает, что вам нужно изменить тип этого столбца TIMESTAMP вместо DATETIME. TIMESTAMP имеет текущую дату и время по умолчанию. Я думаю, что он разрешит вашу проблему.

-3

Вы можете разрешить отметку времени по умолчанию. Сначала рассмотрим, какой набор символов вы используете, например, если u взял utf8, этот набор символов поддерживает все языки, и если вы взяли laten1, этот набор символов поддерживает только английский. Следующий setp, если вы работаете в рамках какого-либо проекта, должен знать часовой пояс клиента и выбирать, что вы являетесь клиентской зоной. Этот шаг является обязательным.

  • 2
    Столбцы DateTime не могут иметь значения по умолчанию. Это документированная «фича». Не все разработчики имеют доступ к изменению кодировки символов. А настройка сервера на его клиентский часовой пояс обычно не возможна, особенно когда клиенты не все являются родными для одного часового пояса.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню