1033

How do you set a default value for a MySQL Datetime column?

In SQL Server it's getdate(). What is the equivalant for MySQL? I'm using MySQL 5.x if that is a factor.

Moppo
  • 18,797
  • 5
  • 65
  • 64
Brian Boatright
  • 36,294
  • 34
  • 81
  • 102
  • 7
    I use CURRENT_TIMESTAMP in my mysql table (not in the query), maybe this can be helpfull too. – Ruben May 15 '12 at 14:48
  • 18
    This feature has now been added to MySQL 5.6.5. Hope this helps someone. http://optimize-this.blogspot.co.uk/2012/04/datetime-default-now-finally-available.html – GhostInTheSecureShell Jul 03 '12 at 14:29
  • @GhostInTheSecureShell quite the mission to install it, at least on Debian, but definitely an awesome feature. I think eventually all these "two CURRENT_TIMESTAMP" questions will be alleviated! – Marc DiMillo Feb 05 '13 at 11:36
  • it is now() function or else you can do with default settings on column level. – Anshul Sharma May 29 '20 at 07:51

26 Answers26

981

IMPORTANT EDIT: It is now possible to achieve this with DATETIME fields since MySQL 5.6.5, take a look at the other post below...

Previous versions can't do that with DATETIME...

But you can do it with 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: IF you define a column with CURRENT_TIMESTAMP ON as default, you will need to ALWAYS specify a value for this column or the value will automatically reset itself to "now()" on update. This means that if you do not want the value to change, your UPDATE statement must contain "[your column name] = [your column name]" (or some other value) or the value will become "now()". Weird, but true. I am using 5.5.56-MariaDB

Halo
  • 1,730
  • 1
  • 8
  • 31
sebthebert
  • 12,196
  • 2
  • 26
  • 37
  • 433
    it's important to note that datetime has a range of 1000-9999, but **the range for timestamp is only 1970-2038**. this can be a problem if your system has to store birthdates, or you have to handle something like the payment plan for a 30-year mortgage. http://dev.mysql.com/doc/refman/5.0/en/datetime.html – Kip Sep 27 '11 at 17:01
  • 19
    Be carefull too with timestamp as it auto-updates magically ... see next answer http://stackoverflow.com/a/1483959/233906 – Cerber Oct 27 '12 at 12:31
  • 7
    It **is** possible from version 5.6.5, see Gustav's answer below (I realize your answer was posted when MySQL was still 5.0!) – Déjà vu Mar 03 '13 at 13:57
  • 7
    @Kip, Hi, is it possible to have a default value for a **`DATE`** column? (not a `datetime` column). – Sajib Acharya Mar 03 '16 at 21:18
  • ti doesn't seem to be possible for DATE columns: you have to use DATETIME data type – Fabio Napodano May 20 '16 at 08:39
  • This CAVEAT is not true for mysql 5.6 unless you actually specified the ON-UPDATE value ie `mydate DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`. Based on documentation and trying it myself. - https://dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html – Curtis Yallop Feb 26 '21 at 01:20
700

In version 5.6.5, it is possible to set a default value on a datetime column, and even make a column that will update when the row is updated. The type definition:

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

Reference: http://optimize-this.blogspot.com/2012/04/datetime-default-now-finally-available.html

Gustav Bertram
  • 14,591
  • 3
  • 40
  • 65
  • 4
    Invalid default value for 'menu_creation_time' – Fernando Trindade Jul 10 '14 at 10:34
  • 2
    @FernandoTrindade You need MySQL version 5.6.5 or later. You can see it working here: http://sqlfiddle.com/#!9/dd2be – Gustav Bertram Jul 10 '14 at 10:38
  • 1
    @GustavBertram, I am using version 5.6.22, but still I got error as follows : CREATE TABLE tbl ( InsertDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, UpdateDate TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP(6) ); Error Code: 1294. Invalid ON UPDATE clause for 'UpdateDate' column – Manish Sapkal Dec 15 '14 at 09:31
  • @ManishSapkal You're using a TIMESTAMP, not a DATETIME. Also, don't make it NULL. – Gustav Bertram Dec 15 '14 at 09:53
  • 4
    I think the "ON UPDATE" syntax is wrong. According to https://dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html it should be `dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` – Dan Bough Jul 20 '17 at 13:48
  • This solution does not work for me. Error when creating table /* Error SQL (1067): Invalid default value for 'creation_time' */ – Jam Mar 24 '18 at 11:45
157

MySQL (before version 5.6.5) does not allow functions to be used for default DateTime values. TIMESTAMP is not suitable due to its odd behavior and is not recommended for use as input data. (See MySQL Data Type Defaults.)

That said, you can accomplish this by creating a Trigger.

I have a table with a DateCreated field of type DateTime. I created a trigger on that table "Before Insert" and "SET NEW.DateCreated=NOW()" and it works great.

starball
  • 20,030
  • 7
  • 43
  • 238
Stephan Unrau
  • 1,699
  • 1
  • 10
  • 5
135

For me the trigger approach has worked the best, but I found a snag with the approach. Consider the basic trigger to set a date field to the current time on insert:

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

This is usually great, but say you want to set the field manually via INSERT statement, like so:

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

What happens is that the trigger immediately overwrites your provided value for the field, and so the only way to set a non-current time is a follow up UPDATE statement--yuck! To override this behavior when a value is provided, try this slightly modified trigger with the IFNULL operator:

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

This gives the best of both worlds: you can provide a value for your date column and it will take, and otherwise it'll default to the current time. It's still ghetto relative to something clean like DEFAULT GETDATE() in the table definition, but we're getting closer!

John Larson
  • 1,359
  • 1
  • 8
  • 8
  • 6
    +1 for acknowledging the caveat with overwriting of explicit user values on insert. – Kip Sep 27 '11 at 17:21
  • 2
    I personally think this is the best way to go. TIMESTAMP does indeed have odd behavior and I would never write code that has a 2038 year limitation. – Eric Jan 24 '12 at 18:30
  • Never mind, I figured it out. Forgot to set the field to allow `NULL`. No warnings anymore. – Kaji Mar 01 '12 at 14:43
  • Triggers are evil! Only ever use them when there's no other way of doing something. Better to upgrade to 5.6.x id you can than use a trigger. – ksymeon Jan 24 '15 at 00:17
  • 4
    In MySQL 5.5 the IFNULL doesn't work on DATETIME; using the above trigger the `dateAdded` will show all '0000-00-00 00:00:00'. Using this does the trick: ` FOR EACH ROW IF NEW.dateAdded = 0 THEN SET NEW.dateAdded = NOW(); END IF;` – Kenney Jun 12 '15 at 14:16
42

I was able to solve this using this alter statement on my table that had two datetime fields.

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;

This works as you would expect the now() function to work. Inserting nulls or ignoring the created_dt and updated_dt fields results in a perfect timestamp value in both fields. Any update to the row changes the updated_dt. If you insert records via the MySQL query browser you needed one more step, a trigger to handle the created_dt with a new timestamp.

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

The trigger can be whatever you want I just like the naming convention [trig]_[my_table_name]_[insert]

Dominic Scheirlinck
  • 2,627
  • 2
  • 23
  • 28
  • I meant to say, If you insert records via the MySQL query browser manually via the grid without an insert() statement the trigger is needed. If you always use an insert statement the trigger is completely unnecessary. –  Oct 12 '09 at 05:07
  • Whoops! I meant The trigger (name) can be whatever you want it to be because the trigger name doesn't affect the functionality at all. Most people will know that, but some folks new to MySQL might not know... –  Oct 12 '09 at 05:18
  • Yikes, sorry about the lack of line breaks. Use the semi-colons to mark the end of each line. –  Oct 12 '09 at 05:27
26

You can use triggers to do this type of stuff.

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;
Josh Lee
  • 171,072
  • 38
  • 269
  • 275
Donald
  • 261
  • 3
  • 2
26

For all those who lost heart trying to set a default DATETIME value in MySQL, I know exactly how you feel/felt. So here is is:

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

Carefully observe that I haven't added single quotes/double quotes around the 0

I'm literally jumping after solving this one :D

Augiwan
  • 2,392
  • 18
  • 22
  • 10
    It doesn't inserts not current time . It will insert '0000-00-00 00:00:00' . – Pit Digger Aug 23 '11 at 15:27
  • 11
    I did not say it sets the current time. Many ppl were/are trying to set a default zero value, but it just doesn't work. We need to eliminate the quotes. As this finding caused a lot of time and frustration, i thought of sharing it with the community. People like you are responsible for users loosing interest in sharing useful info with other people. I seriously dont see any reason to get a -1! Whatever. – Augiwan Aug 24 '11 at 13:41
  • 5
    The same could be achieved with DATETIME NOT NULL. – SineSwiper Feb 17 '14 at 18:25
  • There is one more ` character inside the example sql command, which I cannot edit out, since it is one-character edit only. – quapka May 24 '16 at 09:26
  • your code didnt work for me, here is what worked `ALTER TABLE zones MODIFY created datetime NOT NULL DEFAULT 0;` – Smith Jan 31 '19 at 21:33
23

If you have already created the table then you can use

To change default value to current date time

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

To change default value to '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';
Saveendra Ekanayake
  • 3,153
  • 6
  • 34
  • 44
16

MySQL 5.6 has fixed this problem.

ALTER TABLE mytable CHANGE mydate datetime NOT NULL DEFAULT 'CURRENT_TIMESTAMP'
Hauleth
  • 22,873
  • 4
  • 61
  • 112
Steven Lloyd
  • 187
  • 1
  • 3
14

this is indeed terrible news.here is a long pending bug/feature request for this. that discussion also talks about the limitations of timestamp data type.

I am seriously wondering what is the issue with getting this thing implemented.

Kinjal Dixit
  • 7,777
  • 2
  • 59
  • 68
11

You can use now() to set the value of a datetime column, but keep in mind that you can't use that as a default value.

KernelM
  • 8,776
  • 2
  • 23
  • 16
  • 6
    true. I just tried using now and got an error "Error Code: 1067. Invalid default value.". so what's the answer? ;-) – Brian Boatright Oct 03 '08 at 20:31
  • This is the best solution for compromising MySQL versions 5.5 and 5.6. For version 5.5, predetermine the value of `NOW()` and use it later for the insertion. For version 5.6, simply set `NOW()` as the default value. – Abel Callejo Dec 04 '17 at 19:37
11

I'm running MySql Server 5.7.11 and this sentence:

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

is not working. But the following:

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

just works.

As a sidenote, it is mentioned in the mysql docs:

The DATE type is used for values with a date part but no time part. MySQL retrieves and displays DATE values in 'YYYY-MM-DD' format. The supported range is '1000-01-01' to '9999-12-31'.

even if they also say:

Invalid DATE, DATETIME, or TIMESTAMP values are converted to the “zero” value of the appropriate type ('0000-00-00' or '0000-00-00 00:00:00').

Evhz
  • 8,852
  • 9
  • 51
  • 69
10

Working fine with 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;
Gvs Akhil
  • 2,165
  • 2
  • 16
  • 33
9

For all who use the TIMESTAMP column as a solution i want to second the following limitation from the manual:

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

"The TIMESTAMP data type has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC. It has varying properties, depending on the MySQL version and the SQL mode the server is running in. These properties are described later in this section. "

So this will obviously break your software in about 28 years.

I believe the only solution on the database side is to use triggers like mentioned in other answers.

Fabian
  • 2,428
  • 2
  • 21
  • 19
  • 4
    What if MySQL was updated 20 years from now and that limitation was removed? I'm not sure if that's possible but just a thought. – NessDan May 01 '12 at 21:00
8

While defining multi-line triggers one has to change the delimiter as semicolon will be taken by MySQL compiler as end of trigger and generate error. e.g.

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

While you can't do this with DATETIME in the default definition, you can simply incorporate a select statement in your insert statement like this:

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

Note the lack of quotes around the table.

For MySQL 5.5

Udo Held
  • 12,314
  • 11
  • 67
  • 93
George
  • 67
  • 1
  • 1
6

Here is how to do it on MySQL 5.1:

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

I have no clue why you have to enter the column name twice.

Udo Held
  • 12,314
  • 11
  • 67
  • 93
Samuel
  • 61
  • 1
  • 2
  • 5
    CHANGE is also for renaming the field. The first column name is the 'old', the second column name is the 'new'. It looks redundant if you aren't changing the name of the field. If it's too aesthetically displeasing, try MODIFY. – John Gordon Jan 27 '12 at 20:29
5

If you are trying to set default value as NOW(), I don't think MySQL supports that. In MySQL, you cannot use a function or an expression as the default value for any type of column, except for the TIMESTAMP data type column, for which you can specify the CURRENT_TIMESTAMP as the default.

Vijesh VP
  • 4,508
  • 6
  • 30
  • 32
5

If you set ON UPDATE CURRENT_TIMESTAMP it will take current time when row data update in table.

 CREATE TABLE bar(
        `create_time` TIMESTAMP CURRENT_TIMESTAMP,
        `update_time` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    )
Bhargav Variya
  • 725
  • 1
  • 10
  • 18
4

I think it simple in mysql since mysql the inbuilt function called now() which gives current time(time of that insert).

So your query should look like similarly

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

Thank you.

Deepak N
  • 1,408
  • 3
  • 15
  • 37
2
CREATE TABLE `testtable` (
    `id` INT(10) NULL DEFAULT NULL,
    `colname` DATETIME NULL DEFAULT '1999-12-12 12:12:12'
)

In the above query to create 'testtable', i used '1999-12-12 12:12:12' as default value for DATETIME column colname

Fathah Rehman P
  • 8,401
  • 4
  • 40
  • 42
1

Take for instance If I had a table named 'site' with a created_at and an update_at column that were both DATETIME and need the default value of now, I could execute the following sql to achieve this.

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;

The sequence of statements is important because a table can not have two columns of type TIMESTAMP with default values of CUREENT TIMESTAMP

Joseph Persico
  • 602
  • 7
  • 20
1

Use the following code

DELIMITER $$

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

    DELIMITER ;
Rana Aalamgeer
  • 702
  • 2
  • 8
  • 22
0

If you are trying to set default value as NOW(),MySQL supports that you have to change the type of that column TIMESTAMP instead of DATETIME. TIMESTAMP have current date and time as default..i think it will resolved your problem..

Dhrumil Shah
  • 2,128
  • 5
  • 23
  • 37
0

This is my trigger example:

/************ 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();
-3

You can resolve the default timestamp. First consider which character set you are using for example if u taken utf8 this character set support all languages and if u taken laten1 this character set support only for English. Next setp if you are working under any project you should know client time zone and select you are client zone. This step are mandatory.

David Sykes
  • 48,469
  • 17
  • 71
  • 80
  • 2
    DateTime columns cannot have default values. It's documented 'feature'. Not all developers have access to change their character encoding. And setting the server to it's _clients_ timezone is usually not a possibility, especially when clients are not all native to a single timezone area. – rlb.usa Oct 21 '10 at 18:39