I would like to create a table that has both a column for "created" and another for "updated". The column "created" will be set at insert and never change. The column "updated" will change every time a row is updated. I don't want to mess with either of these columns in the subsequent INSERT or UPDATE statements. So what should my CREATE TABLE statement look like if I start with something like this?
CREATE TABLE IF NOT EXISTS `mydb`.`mytable` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`updated` TIMESTAMP,
`created` TIMESTAMP,
`deleted` TINYINT DEFAULT 0,
`notes` TEXT DEFAULT '',
`description` VARCHAR(100)
) TYPE=innodb;
I seem to be having trouble creating a table with two TIMESTAMP columns. I don't care if the columns are TIMESTAMP or DATETIME or whatever, I just want them to be populated by MySQL without explicit instructions from the insert or update statements.
I would like to be able to do inserts like this:
INSERT INTO `mydb`.`mytable` (notes,description) VALUES ('some note','some description');
and updates like this:
UPDATE `mydb`.`mytable` SET notes=CONCAT(notes,'some more notes') WHERE id=1;
both without having to explicitly set the "created" column or set (or reset) the "updated" column in the insert or update statement.
Try this one to create your table:
CREATE TABLE IF NOT EXISTS db.test_table
(
Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
created DATETIME DEFAULT NULL,
updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted TINYINT DEFAULT 0,
notes TEXT DEFAULT NULL,
description VARCHAR(100)
)
Note that
updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
will allow to update this field automatically.
And set this one for a trigger before inserting records:
DELIMITER $$
CREATE
/*[DEFINER = { user | CURRENT_USER }]*/
TRIGGER `db`.`on_before_insert` BEFORE INSERT
ON `db`.`test_table`
FOR EACH ROW BEGIN
SET new.created = NOW();
END$$
DELIMITER ;
Then you can use this to insert:
INSERT INTO db.test_table(description) VALUES ("Description")
and to update your record
UPDATE db.test_table SET description = "Description 2" where Id=1
And your created and updated fields will be set appropiately.
News flash: In mysql, TIMESTAMP columns are always updated with now() every time any other column in the row is updated - this is a deliberate feature of this datatype.
DATETIME on the other hand does not have this weird behaviour - it's completely normal.
The answer: created must be DATETIME, but due to this bug, you also need a trigger, like this:
CREATE TABLE IF NOT EXISTS mytable (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`updated` TIMESTAMP, -- This will be updated to now(), if you don't set it or set it to null
`created` DATETIME NOT NULL, -- This will never be magically updated once written
`deleted` TINYINT DEFAULT 0,
`notes` TEXT DEFAULT '',
`description` VARCHAR(100)
) TYPE=innodb;
DELIMITER ~
CREATE TRIGGER mytable_insert_trigger
BEFORE INSERT ON mytable
FOR EACH ROW BEGIN
SET NEW.created = CURRENT_TIMESTAMP;
END;~
DELIMITER ;
insert into mytable (notes) values ('test');
select * from mytable;
+----+---------------------+---------------------+---------+-------+-------------+
| id | updated | created | deleted | notes | description |
+----+---------------------+---------------------+---------+-------+-------------+
| 1 | 2011-07-05 11:48:02 | 2011-07-05 11:48:02 | 0 | test | NULL |
+----+---------------------+---------------------+---------+-------+-------------+
Try this:
CREATE TABLE IF NOT EXISTS mydb.mytable
(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
updated DATETIME,
created TIMESTAMP,
deleted TINYINT DEFAULT 0,
notes TEXT DEFAULT '',
description VARCHAR(100)
) TYPE=innodb;
Edit: Use a trigger.
CREATE TRIGGER mytable_update
BEFORE UPDATE ON mydb.mytable
FOR EACH ROW SET NEW.updated = NOW();
alternative is to change the order of timestamp column
OR
set first column DEFAULT value like this
ALTER TABLE `tblname` CHANGE `first_timestamp_column`
`first_timestamp_column` TIMESTAMP NOT NULL DEFAULT 0;
Reference
Unfortunately MySQL doesn't let you have two TIMESTAMP columns in one table. I would use ON UPDATE CURRENT_TIMESTAMP for the updated column and set created manually using the NOW() function.
Related
I have a MySQL database (employee) consists of 5 tables. How to find the recently modified row by column name id in tables?
I tried to find the table using the coding below. It works fine.
USE
information_schema;
SELECT DISTINCT TABLE_NAME
FROM TABLES
WHERE
UPDATE_TIME IS NOT NULL AND UPDATE_TIME < NOW() AND TABLE_SCHEMA = 'employee'
Please help to find the row by column name id (all tables have this column name as identifier) in that table.
I think the work around for this problem is to create a trigger that will insert a record into a different table
CREATE TABLE `table_row_monitor` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tbl` varchar(100) DEFAULT NULL,
`col` varchar(100) DEFAULT NULL,
`val` int,
`dtecreated` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`process_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TRIGGER IF EXISTS chk_pickup_contact_for_delivery;
DELIMITER $$
CREATE TRIGGER `[table_name]_log_row_insert` AFTER INSERT ON `[table_name]` FOR EACH ROW
BEGIN
INSERT INTO table_row_monitor (tbl, col, val)
SELECT '[table_name]', 'id', MAX(id) FROM `[table_name]`;
END$$
DELIMITER ;
just replace the [table_name]
I have not used MySQL in a few years and when I created a new table it did something I was not expecting. I am using MariaDB v5.5.60-MariaDB
I need to create a table that has both a created column and an updated column.
I need the created column to only be set to CURRENT_TIMESTAMP when the row is created and then never change unless I change it explicitly.
I need the updated column to be set to CURRENT_TIMESTAMP both when the row is created and when the row is changed.
If I do the following:
CREATE TABLE user_prefs (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
user VARCHAR(255) NOT NULL,
provider VARCHAR(255) NOT NULL,
pref VARCHAR(128) NOT NULL,
jsondata LONGTEXT,
created timestamp NOT NULL,
modified timestamp NOT NULL,
PRIMARY KEY (id),
UNIQUE INDEX id_UNIQUE (id ASC));
Then the created column is set to:
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
and the modified column is set to:
DEFAULT '0000-00-00 00:00:00'
If I try this:
CREATE TABLE user_prefs (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
user VARCHAR(255) NOT NULL,
provider VARCHAR(255) NOT NULL,
pref VARCHAR(128) NOT NULL,
jsondata LONGTEXT,
created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
modified timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE INDEX id_UNIQUE (id ASC));
Then I get the error **Error Code: 1293. Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
**
So is there a way to automate setting both created and modified on creation of a row and then to change modified every time the row is change?
Thanks in advance.
A table might have automatic initialization of date in only one column in old versions of MySQL. But its behavior fixed in version 5.6.5.
It means you have several ways to avoid this error:
1.You can upgrade your MySQL to the latest version;
Advantages:
native clear implementation of modification dates management in a database side
there aren't excess triggers
Вrawback:
if the current version of MySQL is used in exists projects then upgrading might make some problems.
2.You can create triggers for updating and the creation of a record, as #Simonare said
Advantages:
implementation of modification dates management in a database side
Вrawback:
there are many excess triggers. You'll create two triggers for each table. It means you'll create N*2 triggers for N tables.
3.You can set default value of created column to 0000-00-00 00:00:00 and set default value of updated column to CURRENT_TIMESTAMP(). In this case date of updating will be generated automatically. Also if you write null to created column MySQL will generate current date automatically and set it to the column. For example:
CREATE TABLE example_table (
created TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
updated_at TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP
);
If you execute the following query:
INSERT INTO example_table (created) VALUES (null);
created column will have current date value. MySQL will fill it automatically.
Advantages:
there aren't excess triggers
Вrawback:
implementation of modification dates management in a database side and client application side
4.You can use automatic initialization of date in updated column and use trigger to fill created column. For example:
CREATE TABLE example_table (
created TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
updated_at TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP
);
DELIMITER //
CREATE TRIGGER example_table_set_created_date
BEFORE INSERT
ON example_table FOR EACH ROW
BEGIN
SET NEW.created = CURRENT_TIMESTAMP();
END; //
DELIMITER;
Advantages:
implementation of modification dates management in a database side
Вrawback:
there are many excess triggers. You'll create N triggers for N tables.
you can create trigger for this
DELIMITER //
CREATE TRIGGER user_prefs_before_insert
BEFORE INSERT
ON user_prefs FOR EACH ROW
BEGIN
SET NEW.updated = new.created;
END; //
DELIMITER ;
then another trigger for update
DELIMITER //
CREATE TRIGGER user_prefs_before_update
BEFORE UPDATE
ON user_prefs FOR EACH ROW
BEGIN
SET NEW.updated = CURRENT_TIMESTAMP();
END; //
DELIMITER ;
I want to create a column with default value as null and when any operation is performed it should change to 0. How do i do this in mysql database?
Here example how to add colum in existing table with default value
ALTER TABLE `test1` ADD `no` INT NULL DEFAULT NULL ;
When you call function then you have to write following query
UPDATE test1 SET `no` = '0' WHERE `test1`.`id` =your_id;
CREATE TABLE test
(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
test_id INT,
cost FLOAT(5,2) DEFAULT NULL,
);
each time when you do some operation on that you need to update it as #Sadikhasan
or write a trigger that will update it to zero automatically.
if the operation you want to perform is read then write trigger on ON SELECT
if the operation you want to perform is update then write trigger on ON UPDATE
like wise for others.
I have the following table schema;
CREATE TABLE `db1`.`sms_queue` (
`Id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`Message` VARCHAR(160) NOT NULL DEFAULT 'Unknown Message Error',
`CurrentState` VARCHAR(10) NOT NULL DEFAULT 'None',
`Phone` VARCHAR(14) DEFAULT NULL,
`Created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`LastUpdated` TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP,
`TriesLeft` tinyint NOT NULL DEFAULT 3,
PRIMARY KEY (`Id`)
)
ENGINE = InnoDB;
It fails with the following error:
ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause.
My question is, can I have both of those fields? or do I have to manually set a LastUpdated field during each transaction?
From the MySQL 5.5 documentation:
One TIMESTAMP column in a table can have the current timestamp as the default value for initializing the column, as the auto-update value, or both. It is not possible to have the current timestamp be the default value for one column and the auto-update value for another column.
Changes in MySQL 5.6.5:
Previously, at most one TIMESTAMP column per table could be automatically initialized or updated to the current date and time. This restriction has been lifted. Any TIMESTAMP column definition can have any combination of DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses. In addition, these clauses now can be used with DATETIME column definitions. For more information, see Automatic Initialization and Updating for TIMESTAMP and DATETIME.
There is a trick to have both timestamps, but with a little limitation.
You can use only one of the definitions in one table. Create both timestamp columns like so:
create table test_table(
id integer not null auto_increment primary key,
stamp_created timestamp default '0000-00-00 00:00:00',
stamp_updated timestamp default now() on update now()
);
Note that it is necessary to enter null into both columns during insert:
mysql> insert into test_table(stamp_created, stamp_updated) values(null, null);
Query OK, 1 row affected (0.06 sec)
mysql> select * from test_table;
+----+---------------------+---------------------+
| id | stamp_created | stamp_updated |
+----+---------------------+---------------------+
| 2 | 2009-04-30 09:44:35 | 2009-04-30 09:44:35 |
+----+---------------------+---------------------+
2 rows in set (0.00 sec)
mysql> update test_table set id = 3 where id = 2;
Query OK, 1 row affected (0.05 sec) Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test_table;
+----+---------------------+---------------------+
| id | stamp_created | stamp_updated |
+----+---------------------+---------------------+
| 3 | 2009-04-30 09:44:35 | 2009-04-30 09:46:59 |
+----+---------------------+---------------------+
2 rows in set (0.00 sec)
You can have them both, just take off the "CURRENT_TIMESTAMP" flag on the created field. Whenever you create a new record in the table, just use "NOW()" for a value.
Or.
On the contrary, remove the 'ON UPDATE CURRENT_TIMESTAMP' flag and send the NOW() for that field. That way actually makes more sense.
If you do decide to have MySQL handle the update of timestamps, you can set up a trigger to update the field on insert.
CREATE TRIGGER <trigger_name> BEFORE INSERT ON <table_name> FOR EACH ROW SET NEW.<timestamp_field> = CURRENT_TIMESTAMP;
MySQL Reference: http://dev.mysql.com/doc/refman/5.0/en/triggers.html
This is how can you have automatic & flexible createDate/lastModified fields using triggers:
First define them like this:
CREATE TABLE `entity` (
`entityid` int(11) NOT NULL AUTO_INCREMENT,
`createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`lastModified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`name` varchar(255) DEFAULT NULL,
`comment` text,
PRIMARY KEY (`entityid`),
)
Then add these triggers:
DELIMITER ;;
CREATE trigger entityinsert BEFORE INSERT ON entity FOR EACH ROW BEGIN SET NEW.createDate=IF(ISNULL(NEW.createDate) OR NEW.createDate='0000-00-00 00:00:00', CURRENT_TIMESTAMP, IF(NEW.createDate<CURRENT_TIMESTAMP, NEW.createDate, CURRENT_TIMESTAMP));SET NEW.lastModified=NEW.createDate; END;;
DELIMITER ;
CREATE trigger entityupdate BEFORE UPDATE ON entity FOR EACH ROW SET NEW.lastModified=IF(NEW.lastModified<OLD.lastModified, OLD.lastModified, CURRENT_TIMESTAMP);
If you insert without specifying createDate or lastModified, they will be equal and set to the current timestamp.
If you update them without specifying createDate or lastModified, the lastModified will be set to the current timestamp.
But here's the nice part:
If you insert, you can specify a createDate older than the current timestamp, allowing imports from older times to work well (lastModified will be equal to createDate).
If you update, you can specify a lastModified older than the previous value ('0000-00-00 00:00:00' works well), allowing to update an entry if you're doing cosmetic changes (fixing a typo in a comment) and you want to keep the old lastModified date. This will not modify the lastModified date.
As of MySQL 5.6 its easy-peasy... give it a try:
create table tweet (
id integer not null auto_increment primary key,
stamp_created timestamp default now(),
stamp_updated timestamp default now() on update now(),
message varchar(163)
)
This issue seemed to have been resolved in MySQL 5.6. I have noticed this until MySQL 5.5; here is an example code:
DROP TABLE IF EXISTS `provider_org_group` ;
CREATE TABLE IF NOT EXISTS `provider_org_group` (
`id` INT NOT NULL,
`name` VARCHAR(100) NOT NULL,
`type` VARCHAR(100) NULL,
`inserted` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`insert_src_ver_id` INT NULL,
`updated` TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP,
`update_src_ver_id` INT NULL,
`version` INT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC),
UNIQUE INDEX `name_UNIQUE` (`name` ASC))
ENGINE = InnoDB;
Running this on MySQL 5.5 gives:
ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
Running this on MySQL 5.6
0 row(s) affected 0.093 sec
create table test_table(
id integer not null auto_increment primary key,
stamp_created timestamp default '0000-00-00 00:00:00',
stamp_updated timestamp default now() on update now()
);
source: http://gusiev.com/2009/04/update-and-create-timestamps-with-mysql/
i think this is the better query for stamp_created and stamp_updated
CREATE TABLE test_table(
id integer not null auto_increment primary key,
stamp_created TIMESTAMP DEFAULT now(),
stamp_updated TIMESTAMP DEFAULT '0000-00-00 00:00:00' ON UPDATE now()
);
because when the record created, stamp_created should be filled by now() and stamp_updated should be filled by '0000-00-00 00:00:00'
For mysql 5.7.21 I use the following and works fine:
CREATE TABLE Posts (
modified_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
)
this will add two column for creation and updation.
both will get updated while inserting and updating.
create table users(
id integer not null auto_increment primary key,
created_date timestamp default now(),
modified_date timestamp default now() on update now()
);
My web host is stuck on version 5.1 of mysql so anyone like me that doesn't have the option of upgrading can follow these directions:
http://joegornick.com/2009/12/30/mysql-created-and-modified-date-fields/
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.