I am currently just inserting NOW() into the date field on my database which works just fine but it got me wondering, is there a way to automatically update a DATETIME row upon inserting data?
I found online in some places that I should set the extras to ON UPDATE CURRENT_TIMESTAMP but when doing this I get the following error:
An error occurred when trying to change the field 'uploaded' via
ALTER TABLE `uploads` CHANGE `uploaded` `uploaded` DATETIME
NOT NULL
ON UPDATE CURRENT_TIMESTAMP
COMMENT 'Upload Datetime'
MySQL said:
Invalid ON UPDATE clause for 'uploaded' column
This is what I do and it has always worked
create table if not exists my_table (
index1 char(32) not null primary key,
title varchar(50),
my_timestamp timestamp not null default current_timestamp on update current_timestamp
)
This will have the timestamp on inserts and on updates, it also is valid sql, maybe you are missing the default statement in your query?
It seems the issue was that the column needed to be a TIMESTAMP not DATETIME upon changing it, I was able to successfully add the CURRENT_TIMESTAMP argument.
Seems your query is wrong, try this out works for me:
ALTER TABLE `uploads` CHANGE `uploaded` `uploaded`
DATETIME NOT NULL ON UPDATE CURRENT_TIMESTAMP;
Tested it.
Set the default value for the column upon table creation or alter it later.
In MySQL versions 5.6.5 and later:
default CURRENT_TIMESTAMP
In SQL Server:
default getdate()
In PostgreSQL:
default now()
Maybe this documentation can help you a bit at understanding how to auto update the datetime in a sql database
http://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html
Hope this helped you :)
For most SQL dialects, you can use a DATETIME column with a default of current_timestamp. That handles creation.
create table whatever (
...
updated datetime default current_timestamp
);
Then add an after update trigger.
create trigger foo_updated
after update
on foo
for each row
begin
update foo set updated = current_timestamp where id = new.id;
end;
MySQL has some special syntax to do this. You can make the trigger in your create table statement with an with an on update.
create table whatever (
...
updated datetime default current_timestamp on update current_timestamp
);
And then there's MySQL's timestamp date type. Timestamp will set itself to the current date and time anytime a row is updated... sorta.
The rules are very complicated which is why it's better to use datetime and on update.
When I create a new table
create table test(rId int auto_increment, createtimestamp timestamp not null, PRIMARY KEY (rId));
it creates a table with default schema for
createtimestamp as CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.
Expected behavior was no default set. But it's getting set to default: CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP. Why is this happening?
I can alter this after the creation with ALTER TABLE test CHANGE COLUMN createtimestamp createtimestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ; but can't alter it to ALTER TABLE test CHANGE COLUMN createtimestamp createtimestamp TIMESTAMP NOT NULL ;.
It looks like a default has to be specified but this is exactly what I don't want. How can I achieve a behavior where the default is not set and schema is not null, just after creation of table and without any alteration required?
MySql Version: 5.5.49
The initial answer is correct, but if it's not acceptable to have a default or a NULL in the definition, one might consider either using datetime instead, or upgrading to MySQL 5.6 which allows behaviour change http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_explicit_defaults_for_timestamp.
In an existing database, I've age column (INT). Now I need to set it as dob (DATETIME).
I try doing so through PHPMyAdmin, giving CURRENT_TIMESTAMP as default value as defined by answer with 138 upvotes. However PHPMyAdmin is complaining #1067 - invalid default value for 'dob' as in attached screenshot:
Can someone please suggest why I'm getting that error and how to fix that?
You can't set CURRENT_TIMESTAMP as default value with DATETIME.
But you can do it with TIMESTAMP.
See the difference here.
Words from this blog
The DEFAULT value clause in a data type specification indicates a default value for a column. With one exception, the default value must be a constant; it cannot be a function or an expression.
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.
The exception is that you can specify CURRENT_TIMESTAMP as the default for a TIMESTAMP column.
Set the type of the field as TIMESTAMP too.
I don't think you can achieve that with mysql date. You have to use timestamp or try this approach..
CREATE TRIGGER table_OnInsert BEFORE INSERT ON `DB`.`table`
FOR EACH ROW SET NEW.dateColumn = IFNULL(NEW.dateColumn, NOW());
You're getting that error because the default value current_time is not valid for the type DATETIME. That's what it says, and that's whats going on.
The only field you can use current_time on is a timestamp.
The best way for DateTime is use a Trigger:
/************ 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();
I have two columns in table users namely registerDate and lastVisitDate which consist of datetime data type. I would like to do the following.
Set registerDate defaults value to MySQL NOW()
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?
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
)
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.
My solution
ALTER TABLE `table_name` MODIFY COLUMN `column_name` TIMESTAMP NOT
NULL DEFAULT CURRENT_TIMESTAMP;
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.
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();
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
`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.
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();
This worked for me, using MySQL:
ALTER TABLE `table_name` MODIFY `column_name` datetime NOT NULL DEFAULT NOW();
ALTER TABLE table_name
CHANGE COLUMN date_column_name date_column_name DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;
Finally, This worked for me!
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;
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
This worked for me - just changed INSERT to UPDATE for my table.
INSERT INTO Yourtable (Field1, YourDateField) VALUES('val1', (select now()))
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.
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
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
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.
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!
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]
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;
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
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';
MySQL 5.6 has fixed this problem.
ALTER TABLE mytable CHANGE mydate datetime NOT NULL DEFAULT 'CURRENT_TIMESTAMP'
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.
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.
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').
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.
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;
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 ;
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.
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
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.
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.
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
)
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
Use the following code
DELIMITER $$
CREATE TRIGGER bu_table1_each BEFORE UPDATE ON table1 FOR EACH ROW
BEGIN
SET new.datefield = NOW();
END $$
DELIMITER ;
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..
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
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();
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.