简体   繁体   English

MySQL没有给出默认值时,时间戳的默认值无效。

[英]MySQL Invalid default value for timestamp when no default value is given.

Look at the following sql. 看看下面的sql。

CREATE SCHEMA IF NOT EXISTS `scheduler`;
USE `scheduler` ;
CREATE TABLE IF NOT EXISTS `scheduler`.`JobHistory` (
  `Id` INT NOT NULL AUTO_INCREMENT,
  `Job` INT NOT NULL,
  `StartTime` TIMESTAMP NOT NULL,
  `FinishTime` TIMESTAMP NOT NULL,
  PRIMARY KEY (`Id`),
  INDEX `fk_JobHistory_Job_idx` (`Job` ASC));

It is throwing ErrorCode: 1067. Invalid default value for 'Finish Time' But I'm not giving any default value for finish time, also there is another time stamp StartTime which is exactly same and I'm not getting any exception for that one. 它正在抛出ErrorCode: 1067. Invalid default value for 'Finish Time'但是我没有给出ErrorCode: 1067. Invalid default value for 'Finish Time'任何默认值,还有另一个时间戳StartTime完全相同而且我没有得到任何例外。

Although @jsnplank is right that timestamps are treated differently and you should consider using datetime datatype for these 2 particular columns, however, he fails to explain the error message. 尽管@jsnplank是正确的,时间戳的处理方式不同,但您应该考虑对这两个特定列使用datetime数据类型,但是,他无法解释错误消息。

The error message is most likely the result of a combination of how mysql treats timestamp fields when no default value is provided and your sql mode settings. 错误消息很可能是mysql在没有提供默认值和sql模式设置时如何处理时间戳字段的结果。

  1. You define both timestamp columns as not null, without any specific default value set. 您将两个timestamp列定义为not null,而不设置任何特定的默认值。 This means that the 1st timestamp column's default value will be current_timestamp() and will also be updated to current_timestamp() whenever the record changes. 这意味着第一个时间戳列的默认值将是current_timestamp(),并且每当记录更改时也将更新为current_timestamp()。 This is why the 1st timestamp field does not generate an error message, no matter which of the 2 is the 1st one. 这就是为什么第一个时间戳字段不会生成错误消息,无论哪一个是第一个。

    However, the 2nd not null timestamp column's default value will be '0000-00-00 00:00:00' if you do not explicitly define a default value. 但是,如果您没有明确定义默认值,则第二个非空时间戳列的默认值将为'0000-00-00 00:00:00'。

    See this blog post for more details . 有关详细信息,请参阅此博客文章

  2. Probably no_zero_date sql mode is also enabled on your server either explicitly or as part of strict sql mode. 可能在您的服务器上显式或作为严格的sql模式的一部分启用了no_zero_date sql模式。 This sql mode generates an error if you want set '0000-00-00 00:00:00' as a default value or would like to insert this value into any date field. 如果您希望将'0000-00-00 00:00:00'设置为默认值,或者希望将此值插入任何日期字段,则此sql模式会生成错误。

So, you can use timestamp data type in your table, but make the 2nd one either nullable or provide 0 or any valid date (such as the epoch) as an explicit default value. 因此,您可以在表中使用timestamp数据类型,但是将第二个数据类型设置为可空或提供0或任何有效日期(例如epoch)作为显式默认值。

Since you are marking start and end dates with these fields, uding datetime instead of timestamp as datatype may be a good idea. 由于您使用这些字段标记开始日期和结束日期,因此将日期时间而不是时间戳作为数据类型可能是一个好主意。

You should be using DATETIME data types for your StartTime and FinishTime columns. 您应该将DATETIME数据类型用于StartTime和FinishTime列。 TIMESTAMPS have a very specific usage. TIMESTAMPS具有非常特定的用途。 See http://www.sqlteam.com/article/timestamps-vs-datetime-data-types 请参见http://www.sqlteam.com/article/timestamps-vs-datetime-data-types

Referencing an article from the year 2000 is not really helpful as a lot already changed since then and might not be true any longer. 引用2000年的一篇文章并不是很有用,因为从那时起已经有很多变化,而且可能不再适用。 As others already mentioned in other related questions, TIMESTAMP values reference a specific point in time relative to January 1st, 1970 at UTC. 正如其他相关问题中已提到的那些,TIMESTAMP值引用相对于1970年1月1日UTC的特定时间点。 DATETIME values on the contrary just store some date and time without a reference to any point in time. 相反,DATETIME值只存储一些日期和时间而不引用任何时间点。 They are more like display values, a clock on the wall that shows you some value. 它们更像是显示值,墙上的时钟显示了一些价值。 A datetime of 2018-01-12 14:00:00 might be a different time in different timezones if you want to keep track of when something happened. 如果您想跟踪发生的2018-01-12 14:00:00日期时间2018-01-12 14:00:00可能是不同时区的不同时间。

TIMESTAMP on the other hand is always stored as UTC and when read or used in datetime function, automatically is converted back to the connection's or database default timezone. 另一方面,TIMESTAMP始终存储为UTC,当在datetime函数中读取或使用时,会自动转换回连接或数据库默认时区。 So when your connection is set to +02:00, the actual value that will be stored in the TIMESTAMP column, will be 2018-01-12 12:00:00 instead of 2018-01-12 14:00:00 . 因此,当您的连接设置为+02:00时,将存储在TIMESTAMP列中的实际值将是2018-01-12 12:00:00而不是2018-01-12 14:00:00 When you then read the column with a +05:00 connection, you will see 2018-01-12 17:00:00 . 然后,当您使用+05:00连接读取列时,您将看到2018-01-12 17:00:00 A DATETIME value would always stay at 2018-01-12 14:00:00 no matter what timezone is set for the database or connection. 无论为数据库或连接设置了什么时区,DATETIME值始终保持在2018-01-12 14:00:00

So for tracking when something has happened or when something will/should happen, TIMESTAMP is the way to go. 因此,为了追踪发生了什么事情或什么时候/应该发生的事情,TIMESTAMP是要走的路。 When you just want to store a fixed date time independent of the timezone, then use DATETIME (eg users shall receive an email at 2 in the morning, as 2 in the morning is the same for everyone). 当您只想存储与时区无关的固定日期时间时,请使用DATETIME(例如,用户应在凌晨2点收到电子邮件,因为早上2点对每个人都是相同的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM