215

I have two columns in table users namely registerDate and lastVisitDate which consist of datetime data type. I would like to do the following.

  1. Set registerDate defaults value to MySQL NOW()
  2. Set lastVisitDate default value to 0000-00-00 00:00:00 Instead of null which it uses by default.

Because the table already exists and has existing records, I would like to use Modify table. I've tried using the two piece of code below, but neither works.

ALTER TABLE users MODIFY registerDate datetime DEFAULT NOW()
ALTER TABLE users MODIFY registerDate datetime DEFAULT CURRENT_TIMESTAMP;

It gives me Error : ERROR 1067 (42000): Invalid default value for 'registerDate'

Is it possible for me to set the default datetime value to NOW() in MySQL?

ryanyuyu
  • 6,366
  • 10
  • 48
  • 53
Ibrahim Azhar Armar
  • 25,288
  • 35
  • 131
  • 207

13 Answers13

270

As of MySQL 5.6.5, you can use the DATETIME type with a dynamic default value:

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

Or even combine both rules:

modification_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

Reference:
http://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html
http://optimize-this.blogspot.com/2012/04/datetime-default-now-finally-available.html

Prior to 5.6.5, you need to use the TIMESTAMP data type, which automatically updates whenever the record is modified. Unfortunately, however, only one auto-updated TIMESTAMP field can exist per table.

CREATE TABLE mytable (
  mydate TIMESTAMP
)

See: http://dev.mysql.com/doc/refman/5.1/en/create-table.html

If you want to prevent MySQL from updating the timestamp value on UPDATE (so that it only triggers on INSERT) you can change the definition to:

CREATE TABLE mytable (
  mydate TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
Simon East
  • 55,742
  • 17
  • 139
  • 133
Johan
  • 74,508
  • 24
  • 191
  • 319
  • 81
    i really don't want to use timestamp. – Ibrahim Azhar Armar Apr 28 '11 at 12:18
  • @ibrahim, why not?, you state `ALTER TABLE users MODIFY registerDate datetime DEFAULT CURRENT_TIMESTAMP;` as an explicit example in the question. – Johan Apr 28 '11 at 12:20
  • 2
    @Ibrahim: timestamp is your only chance. If you use a datetime field you have to insert record using now() everytime. – Nicola Cossu Apr 28 '11 at 12:22
  • 9
    Manual speaks clear: "This means, for example, that you cannot set the default for a date column to be the value of a function such as NOW() or CURRENT_DATE". – Nicola Cossu Apr 28 '11 at 12:24
  • 21
    @Johan `DATETIME` is often prefered to do the range it can hold: '1000-01-01 00:00:00' to '9999-12-31 23:59:59' compared to `TIMESTAMPS`'s '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC. For purposes of storing birth dates, or something more than 30 years in the future for instance. – user17753 Oct 12 '12 at 16:15
  • Also `ALTER TABLE users MODIFY registerDate TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP;` – Timo Huovinen Aug 06 '13 at 10:08
  • better link to the manual: http://dev.mysql.com/doc/refman/5.1/en/timestamp-initialization.html which explicitly says that a bare TIMESTAMP column as above gets the "default current_timestamp" and "on update current_timestamp" behaviours. – Móż Sep 18 '13 at 04:30
  • 2
    there can be only one TIMESTAMP column with DEFAULT CURRENT_TIMESTAMP. so if you wish use 2 colums, such 'date_created', 'last_edit' - this solution isn`t work – RouR Feb 05 '14 at 05:23
  • 5
    @nickrulez You no longer are restricted to `timestamp` for this behavior as of MySQL 5.6 – Dan Esparza Feb 18 '15 at 01:14
  • What will be `modification_time ` on the insert? Will it be `NULL`? – Krishnadas PC Jul 11 '18 at 06:31
  • this works `dateUpdated` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, – Gvs Akhil Feb 16 '20 at 10:22
71

I use a trigger as a workaround to set a datetime field to NOW() for new inserts:

CREATE TRIGGER `triggername` BEFORE INSERT ON  `tablename` 
FOR EACH ROW 
SET NEW.datetimefield = NOW()

it should work for updates too

Answers by Johan & Leonardo involve converting to a timestamp field. Although this is probably ok for the use case presented in the question (storing RegisterDate and LastVisitDate), it is not a universal solution. See datetime vs timestamp question.

Community
  • 1
  • 1
wardk
  • 1,143
  • 8
  • 12
  • 4
    This should be the accepted answer, but specifically you should edit it to make it obvious it is for a datetime field. The original poster wants to know how to solve it for a datetime field, and `use a timestamp` is a foolish workaround if you really learn the difference between these two data types. – phpguru Mar 14 '14 at 07:51
47

My solution

ALTER TABLE `table_name` MODIFY COLUMN `column_name` TIMESTAMP NOT
NULL DEFAULT CURRENT_TIMESTAMP;
Leonardo
  • 731
  • 6
  • 11
14

EUREKA !!!


For all those who lost heart trying to set a default DATETIME value in MySQL, I know exactly how you feel/felt. So here it 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.


Important update:

This answer was posted long back. Back then, it worked on my (probably latest) installation of MySQL and I felt like sharing it. Please read the comments below before you decide to use this solution now.

Augiwan
  • 2,392
  • 18
  • 22
  • 17
    It depends on expectations... - This solution allows you to have the field NOT NULL, since a default is provided. - This solution will not set the field to NOW(). – CodeReaper Dec 12 '12 at 10:36
  • 10
    This doesn't answer the original question; the answer should state that clearly. – Matt Browne Jul 30 '13 at 16:54
  • 2
    Be aware that the TRADITIONAL SQL mode includes NO_ZERO_DATE, so the above will not work in that case. – Móż Sep 18 '13 at 04:31
  • Based on the answers provided, sounds like if you will not sacrifice DATETIME to be TIMESTAMP, then you must use triggers. – Chris Nov 30 '13 at 17:47
  • This answer is not right. '0000-00-00 00:00:00' in single quotes is the "zero" equivalent for a non-null datetime field and should be avoided if possible for myriad reasons. Use a trigger to update a datetime to NOW() automatically if you really don't want to use a timestamp. – phpguru Mar 14 '14 at 07:47
  • 1
    This solution will have some apis crazy with "OMG its a ZERO date! What an HERESY! We can't convert 'this' to a java.lang.Date/System.DateTime! OMG! -crashes-". – Felype May 05 '15 at 18:19
  • Like @CodeReaper said, it depends on what you're trying to do. I wanted it to be set to "0000-00-00 00:00:00", so this works perfectly for me and I'm upvoting it. – Natsukane Oct 01 '15 at 09:52
  • Zero date is not current time! ;P – diegodsp Oct 14 '15 at 19:11
  • If I remember correctly, this answers the second sub-question. – Augiwan Oct 18 '15 at 09:54
11

On versions mysql 5.6.5 and newer, you can use precise datetimes and set default values as well. There is a subtle bit though, which is to pass in the precision value to both the datetime and the NOW() function call.

This Example Works:

    ALTER TABLE my_table MODIFY created datetime(6) NOT NULL DEFAULT NOW(6);

This Example Does not Work:

    ALTER TABLE my_table MODIFY created datetime(6) NOT NULL DEFAULT NOW();
Matteius
  • 358
  • 1
  • 4
  • 9
3

mysql 5.6 docs say that CURRENT_TIMESTAMP can be used as default for both TIMESTAMP and DATETIME data types:

http://dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html

1
`ALTER TABLE  `table_name` CHANGE `column_name` 
    timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP 
    ON UPDATE CURRENT_TIMESTAMP

Can be used to update the timestamp on update.

Dyrandz Famador
  • 4,499
  • 5
  • 25
  • 40
veelen
  • 1,916
  • 19
  • 26
1

The best way is using "DEFAULT 0". Other way:

    /************ 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();
Manuel
  • 836
  • 13
  • 30
0

This worked for me, using MySQL:

ALTER TABLE `table_name` MODIFY `column_name` datetime NOT NULL DEFAULT NOW();
rosshump
  • 370
  • 1
  • 4
  • 21
0
ALTER TABLE table_name
  CHANGE COLUMN date_column_name date_column_name DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;

Finally, This worked for me!

Eagle_Eye
  • 1,044
  • 1
  • 14
  • 26
0
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
-1

This worked for me - just changed INSERT to UPDATE for my table.

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

Not sure if this is still active but here goes.

Regarding setting the defaults to Now(), I don't see that to be possible for the DATETIME data type. If you want to use that data type, set the date when you perform the insert like this:

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

My version of mySQL is 5.5

Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
George
  • 67
  • 1
  • 1