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


898

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

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


4
Я использую CURRENT_TIMESTAMP в моей таблице MySQL (не в запросе), может быть, это тоже может быть полезным.
Рубен

15
Эта функция была добавлена ​​в MySQL 5.6.5. Надеюсь, это кому-нибудь поможет. optimize-this.blogspot.co.uk/2012/04/…
GhostInTheSecureShell

@GhostInTheSecureShell - настоящая миссия, чтобы установить его, по крайней мере, на Debian, но определенно отличная функция. Я думаю, что в конечном итоге все эти "два CURRENT_TIMESTAMP" вопроса будут смягчены!
Марк ДиМилло

теперь это функция (), иначе вы можете сделать настройки по умолчанию на уровне столбца.
Аншул Шарма

Ответы:


862

ВАЖНОЕ РЕДАКТИРОВАНИЕ: теперь возможно достигнуть этого с полями 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 **


400
важно отметить, что у datetime есть диапазон 1000-9999, но диапазон для метки времени - только 1970-2038 . это может быть проблемой, если ваша система должна хранить даты рождения или вам нужно что-то вроде плана оплаты для 30-летней ипотеки. dev.mysql.com/doc/refman/5.0/en/datetime.html
Кип

13
Будьте осторожны с меткой времени, так как она автоматически обновляется магическим образом ... см. Следующий ответ stackoverflow.com/a/1483959/233906
Cerber

6
Это является возможным , начиная с версии 5.6.5, см ответа Густава ниже (я понимаю , ваш ответ был отправлен , когда MySQL был еще 5,0!)
e2-e4

4
@Kip, Привет, возможно ли иметь значение по умолчанию для DATEстолбца? (не datetimeстолбец).
Саджиб Ачарья

Это не представляется возможным для столбцов DATE: вы должны использовать тип данных DATETIME
Фабио Наподано

599

В версии 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


3
Неверное значение по умолчанию для «menu_creation_time»
Фернандо Триндаде

2
@FernandoTrindade Вам нужна MySQL версии 5.6.5 или новее. Вы можете увидеть, как это работает здесь: sqlfiddle.com/#!9/dd2be
Густав Бертрам

1
@GustavBertram, я использую версию 5.6.22, но все равно я получил ошибку следующим образом: CREATE TABLE tbl (InsertDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, UpdateDate TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP (6)); Код ошибки: 1294. Недопустимое условие ON UPDATE для столбца «UpdateDate»
Маниш Сапкал

@ManishSapkal Вы используете TIMESTAMP, а не DATETIME. Кроме того, не делайте это NULL.
Густав Бертрам

1
Я думаю, что синтаксис "ОБНОВЛЕНИЕ" неверен. Согласно dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html это должно бытьdt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
Дэн Боу

148

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

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

У меня есть таблица с полем DateCreated типа DateTime. Я создал триггер на этой таблице «Перед вставкой» и « SET NEW.DateCreated=NOW()», и он прекрасно работает.

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


21
CREATE TRIGGER trigger_foo_SetCreatedAt ПЕРЕД ВСТАВКОЙ НА foo ДЛЯ КАЖДОЙ СТРОКИ УСТАНОВЛЕНА NEW.created_at = UTC_TIMESTAMP ();
kgriffs

5
Вы, вероятно, лучше использовать временную метку, чем триггер для будущего здравомыслия (обслуживания). Это слишком тривиальный вариант использования для триггера, хотя это решение.
getWeberForStackExchange

8
Возможно, вы захотите установить только значение по умолчаниюIF NEW.created_at IS NOT NULL
Петр Пеллер,

132

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

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 года.
Эрик

Неважно, я понял это. Забыл установить поле для разрешения NULL. Никаких предупреждений больше.
Кадзи

Триггеры злые! Используйте их только тогда, когда нет другого способа что-либо сделать. Лучше обновить до 5.6.x с идентификатором, чем использовать триггер.
Ksymeon

4
В MySQL 5.5 IFNULL не работает с DATETIME; с помощью вышеуказанного триггера dateAddedпокажет все «0000-00-00 00:00:00». Использование этого делает трюк: `FOR EACH ROW IF NEW.dateAdded = 0 THEN SET NEW.dateAdded = NOW (); END IF; `
Кенни

28

Я смог решить эту проблему с помощью этого оператора 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 () будет работать. Вставка пустых значений или игнорирование полей созданного и обновленного приводит к идеальному значению метки времени в обоих полях. Любое обновление строки изменяет updated_dt. Если вы вставляете записи через браузер запросов MySQL, вам понадобится еще один шаг - триггер для обработки create_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]


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

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

Yikes, извините за отсутствие разрывов строк. Используйте точки с запятой, чтобы отметить конец каждой строки.

24

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

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;

18

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

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

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

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


8
Не вставляет не текущее время. Будет вставлено «0000-00-00 00:00:00».
Яма Копатель

8
Я не говорил, что устанавливает текущее время. Многие пользователи были / пытаются установить нулевое значение по умолчанию, но оно просто не работает. Нам нужно исключить цитаты. Поскольку этот вывод вызвал много времени и разочарований, я подумал поделиться им с сообществом. Люди, подобные вам, несут ответственность за то, что пользователи теряют интерес к обмену полезной информацией с другими людьми. Я серьезно не вижу причин, чтобы получить -1! Без разницы.
Augiwan

3
То же самое может быть достигнуто с DATETIME NOT NULL.
Брендан Берд

В примере команды sql есть еще один символ `, который я не могу отредактировать, поскольку он предназначен только для редактирования одного символа.
квапка

Ваш код не работал для меня, вот что сработалоALTER TABLE zones MODIFY created datetime NOT NULL DEFAULT 0;
Смит


14

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

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

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

13

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

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



9

Я использую 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 в формате «ГГГГ-ММ-ДД». Поддерживаемый диапазон: от 1000-01-01 до 9999-12-31.

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

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


8

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


4
правда. Я только что попытался использовать сейчас и получил ошибку «Код ошибки: 1067. Неверное значение по умолчанию.». так какой ответ? ;-)
Брайан Боатрайт

Это лучшее решение для компрометации версий MySQL 5.5 и 5.6. Для версии 5.5 предварительно определите значение NOW()и используйте его позже для вставки. Для версии 5.6 просто установите NOW()значение по умолчанию.
Абель

8

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

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

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

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

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


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

7

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

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

5

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

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

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


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

5

Хотя вы не можете сделать это DATETIMEв определении по умолчанию, вы можете просто включить оператор select в ваш оператор вставки следующим образом:

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

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

Для MySQL 5.5


3

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


3

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

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

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

Спасибо.


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

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

DELIMITER $$

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

    DELIMITER ;

0

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


0

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

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

ALTER TABLE `site` CHANGE` create_at` `create_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

Это мой триггерный пример:

/************ 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

Хорошо работает с MySQL 8.x

CREATE TABLE `users` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `dateCreated` datetime DEFAULT CURRENT_TIMESTAMP,
      `dateUpdated` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`),
      UNIQUE KEY `mobile_UNIQUE` (`mobile`)
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-3

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


2
Столбцы DateTime не могут иметь значения по умолчанию. Это документированная «фича». Не все разработчики имеют доступ к изменению кодировки символов. И настройка сервера на его часовой пояс клиента обычно не возможна, особенно когда клиенты не все являются родными для одного часового пояса.
rlb.usa
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.