将NOW()设置为datetime数据类型的默认值?

Ibr*_*mar 190 mysql sql datetime mysql-error-1067

我在表用户中有两列,registerDate and lastVisitDate它们包含日期时间数据类型.我想做以下几点.

  1. 将registerDate默认值设置为MySQL NOW()
  2. 将lastVisitDate默认值设置为默认0000-00-00 00:00:00使用的null而不是null.

因为表已经存在并且有现有记录,所以我想使用Modify表.我尝试过使用下面的两段代码,但都不行.

ALTER TABLE users MODIFY registerDate datetime DEFAULT NOW()
ALTER TABLE users MODIFY registerDate datetime DEFAULT CURRENT_TIMESTAMP;
Run Code Online (Sandbox Code Playgroud)

它给了我错误: ERROR 1067 (42000): Invalid default value for 'registerDate'

我可以在MySQL中将默认日期时间值设置为NOW()吗?

Joh*_*ica 232

从MySQL 5.6.5开始,您可以使用DATETIME具有动态默认值的类型:

CREATE TABLE foo (
    creation_time      DATETIME DEFAULT   CURRENT_TIMESTAMP,
    modification_time  DATETIME ON UPDATE CURRENT_TIMESTAMP
)
Run Code Online (Sandbox Code Playgroud)

甚至结合两个规则:

modification_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
Run Code Online (Sandbox Code Playgroud)

参考:
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的

在5.6.5之前,您需要使用TIMESTAMP数据类型,该类型会在修改记录时自动更新.然而,遗憾的是,TIMESTAMP每个表只能存在一个自动更新的字段.

CREATE TABLE mytable (
  mydate TIMESTAMP
)
Run Code Online (Sandbox Code Playgroud)

请参阅:http://dev.mysql.com/doc/refman/5.1/en/create-table.html

如果您想阻止MySQL更新时间戳值UPDATE(以便它只触发INSERT),您可以将定义更改为:

CREATE TABLE mytable (
  mydate TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
Run Code Online (Sandbox Code Playgroud)

  • 我真的不想使用时间戳. (80认同)
  • @Johan`DATETIME`通常更喜欢它可以容纳的范围:'1000-01-01 00:00:00'到'9999-12-31 23:59:59'与'TIMESTAMPS`''1970相比-01-01 00:00:01'UTC到'2038-01-19 03:14:07'UTC.例如,为了存储出生日期或将来超过30年的事情. (18认同)
  • 手动说清楚:"这意味着,例如,您不能将日期列的默认值设置为函数的值,如NOW()或CURRENT_DATE". (9认同)
  • @nickrulez从MySQL 5.6开始,你不再局限于`timestamp`这种行为 (5认同)
  • @Ibrahim:时间戳是你唯一的机会.如果使用datetime字段,则必须每次使用now()插入记录. (2认同)
  • 只有一个带有DEFAULT CURRENT_TIMESTAMP的TIMESTAMP列.所以,如果你想使用2个colums,例如'date_created','last_edit' - 这个解决方案不起作用 (2认同)

war*_*rdk 70

我使用触发器作为解决方法,为新插入设置日期时间字段为NOW():

CREATE TRIGGER `triggername` BEFORE INSERT ON  `tablename` 
FOR EACH ROW 
SET NEW.datetimefield = NOW()
Run Code Online (Sandbox Code Playgroud)

它也适用于更新

Johan和Leonardo的回答涉及转换为时间戳字段.虽然这可能对问题中提供的用例(存储RegisterDate和LastVisitDate)没有问题,但它不是一个通用的解决方案.请参阅datetime vs timestamp问题.

  • 这应该是已接受的答案,但具体来说,您应该对其进行编辑以使其明显适用于日期时间字段.原始海报想要知道如何为日期时间字段解决它,如果您真正了解这两种数据类型之间的差异,那么"使用时间戳"是一种愚蠢的解决方法. (4认同)

Leo*_*rdo 44

我的解决方案

ALTER TABLE `table_name` MODIFY COLUMN `column_name` TIMESTAMP NOT
NULL DEFAULT CURRENT_TIMESTAMP;
Run Code Online (Sandbox Code Playgroud)

  • 这仍然是`TIMESTAMP`列的解决方案.没有人要求"TIMESTAMP"...... (27认同)
  • 是的,这不是问题的答案.TIMESTAMP是DATETIME的不同类型的字段. (2认同)

Aug*_*wan 13

EUREKA !!!


对于那些在MySQL中设置默认DATETIME值的人而言,我确切地知道你的感受/感受.所以这里是:

`ALTER TABLE  `table_name` CHANGE `column_name` DATETIME NOT NULL DEFAULT 0
Run Code Online (Sandbox Code Playgroud)

仔细观察我没有0附近添加单引号/双引号.


重要更新:

这个答案很久以前发布了.那时候,它适用于我的(可能是最新的)MySQL安装,我感觉就像分享它一样.在您决定立即使用此解决方案之前,请阅读以下注释.

  • 这取决于期望... - 此解决方案允许您将字段设为NOT NULL,因为提供了默认值. - 此解决方案不会将字段设置为NOW(). (16认同)
  • 这不回答原来的问题; 答案应该清楚地说明. (10认同)
  • 请注意,TRADITIONAL SQL模式包含NO_ZERO_DATE,因此上述情况在这种情况下不起作用. (2认同)

Mat*_*ius 6

在 mysql 5.6.5 和更新版本上,您可以使用精确的日期时间并设置默认值。但是有一个微妙的地方,就是将精度值传递给 datetime 和 NOW() 函数调用。

这个例子有效:

    ALTER TABLE my_table MODIFY created datetime(6) NOT NULL DEFAULT NOW(6);
Run Code Online (Sandbox Code Playgroud)

这个例子不起作用:

    ALTER TABLE my_table MODIFY created datetime(6) NOT NULL DEFAULT NOW();
Run Code Online (Sandbox Code Playgroud)