Як встановити значення за замовчуванням для стовпця 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" питання будуть полегшені!
Marc DiMillo

це тепер () функція, інакше ви можете робити з налаштуваннями за замовчуванням на рівні стовпця.
Аншул Шарма

Відповіді:


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 повинен містити "[назва вашого стовпця] = [назва вашого стовпця]" (або якесь інше значення) або значення стане "зараз ()". Дивно, але правда. Я сподіваюся, що це допомагає. Я використовую 5.5.56-MariaDB **


400
важливо зауважити, що дата має діапазон 1000-9999, але діапазон для позначки часу становить лише 1970-2038 . це може бути проблемою, якщо вашій системі доводиться зберігати дані про народження або вам доведеться обробляти щось на зразок плану платежів за 30-річну іпотеку. dev.mysql.com/doc/refman/5.0/uk/datetime.html
Кіп

13
Будьте обережні і з часовою позначкою, оскільки вона автоматично оновлюється автоматично ... див. Наступну відповідь stackoverflow.com/a/1483959/233906
Чербер

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

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

ти, здається, не можливий для стовпців DATE: ти повинен використовувати тип даних DATETIME
Fabio Napodano

598

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

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'
Fernando Trindade

2
@FernandoTrindade Вам потрібна версія MySQL 5.6.5 або новіша версія. Побачити його можна тут: sqlfiddle.com/#!9/dd2be
Густав Бертрам

1
@GustavBertram, я використовую версію 5.6.22, але все ж я помилився так: СТВОРИТИ ТАБЛИЦЮ tbl (InsertDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, UpdateDate TIMESTAMP NULL НА ОНОВЛЕННЯ CURRENT_TIMESTAMP (6)); Код помилки: 1294. Недійсний пункт ON UPDATE для стовпчика "UpdateDate"
Manish Sapkal

@ManishSapkal Ви використовуєте TIMESTAMP, а не DATETIME. Крім того, не робіть це НУЛІ.
Густав Бертрам

1
Я думаю, що синтаксис "ON UPDATE" неправильний. Відповідно до dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html це має бутиdt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
Dan Bough

148

MySQL ( до версії 5.6.5 ) не дозволяє використовувати функції для значень DateTime за замовчуванням. TIMESTAMP не підходить через його дивну поведінку і не рекомендується використовувати як вихідні дані. (Див. Значення за замовчуванням типу даних MySQL .)

Однак це можна зробити , створивши тригер .

У мене є таблиця з полем DateCreate типу DateTime. Я створив на цій таблиці тригер "Перед вставкою" та " SET NEW.DateCreated=NOW()", і він чудово працює.

Я сподіваюся, що це комусь допоможе.


21
СТВОРИТИ ТРІГЕРЕР тригер_foo_SetCreateAt ПЕРЕД ВСТАВЛЕННЯ ДЛЯ КОЖОГО РЯДОГО НАСТРОЙКА NEW.create_at = UTC_TIMESTAMP ();
кгріфи

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 (); КОНЕЦЬ, АКО; `
Кенні

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 () працює. Вставлення нулів або ігнорування полів create_dt та updated_dt призводить до ідеального значення часової позначки в обох полях. Будь-яке оновлення рядка змінює оновлений_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 (), потрібен тригер. Якщо ви завжди використовуєте оператор вставки, тригер абсолютно непотрібний.

Ого! Я мав на увазі тригер (ім’я) може бути будь-яким, що ви хочете, щоб це було, тому що ім'я тригера зовсім не впливає на функціональність. Більшість людей це буде знати, але деякі люди, нові для MySQL, можуть не знати ...

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".
Pit Digger

8
Я не сказав, що він встановлює поточний час. Багато ppl намагалися встановити нульове значення за замовчуванням, але це просто не працює. Нам потрібно усунути цитати. Оскільки ця знахідка викликала багато часу і розчарування, я думав поділитися цим спільнотою. Такі люди, як ви, відповідальні за те, що користувачі втрачають інтерес до обміну корисною інформацією з іншими людьми. Я серйозно не бачу причин отримати -1! Що б там не було.
Augiwan

3
Те ж саме можна досягти за допомогою DATETIME NOT NULL.
Брендан Берд

Всередині прикладу sql є ще один `символ, який я не можу редагувати, оскільки це лише односимвольне редагування.
quapka

ваш код не працював для мене, ось що спрацювало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 у форматі "РРРР-MM-DD". Підтримується діапазон від "1000-01-01" до "9999-12-31".

навіть якщо вони також кажуть:

Недійсні значення DATE, DATETIME або TIMESTAMP перетворюються на значення "нуль" відповідного типу ("0000-00-00" або "0000-00-00 00:00:00").


8

Ви можете використовувати now () для встановлення значення стовпця datetime, але майте на увазі, що ви не можете використовувати це як значення за замовчуванням.


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

Це найкраще рішення для компрометації версій 5.5 та 5.6 MySQL. Для версії 5.5 попередньо визначте значення NOW()та використовуйте його пізніше для вставки. Для версії 5.6 просто встановіть NOW()як значення за замовчуванням.
Abel Callejo

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
Зміна також призначена для перейменування поля. Назва першого стовпця - "стара", друга назва стовпця - "нова". Це виглядає зайвим, якщо ви не змінюєте назву поля. Якщо це занадто естетично не цікаво, спробуйте 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" із створеним_at та стовпцем update_at, які були і DATETIME, і потрібне значення за замовчуванням зараз, я міг би виконати наступний sql, щоб досягти цього.

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

ALTER TABLE `сайт` ЗМІНА` 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

Це мій приклад запуску:

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

Ви можете вирішити часову позначку за замовчуванням. Спочатку розгляньте, який набір символів ви використовуєте, наприклад, якщо u взяли utf8, цей набір символів підтримує всі мови, а якщо у вас прийнято laten1, цей набір символів підтримує лише англійську мову. Наступна установка, якщо ви працюєте в будь-якому проекті, ви повинні знати часовий пояс клієнта і вибрати, що ви - клієнтська зона. Цей крок є обов’язковим.


2
У стовпцях DateTime не можуть бути значення за замовчуванням. Це документально підтверджена функція. Не всі розробники мають доступ до зміни кодування символів. І встановити сервер на його клієнтів часовий пояс, як правило, не є можливим, особливо коли клієнти не всі є рідними для однієї області часового поясу.
rlb.usa
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.