从now()到日期字段的隐式转换

时间:2010-04-27 17:26:33

标签: mysql implicit-cast

我有MySQL 5.1的问题。日期时间数据类型不会隐式转换为与日期列匹配。

 SELECT * FROM my_table WHERE my_date_field = NOW()

此请求不会使用MySQL 5.1返回任何行,但适用于5.0版。 如果我们使用CURDATE()而不是NOW(),它在MySQL 5.0和MySQL 5.1中都有效。 如果强制转换是显式的(CAST(NOW() AS DATE)),它也适用于MySQL 5.0和MySQL 5.1。

问题仅出现在datetime到date的隐式强制转换中。没有人已经遇到过这个问题或者有关于如何解决这个问题的线索吗? 我知道使用NOW()而不是CURTIME()并不是最好的,但这不是问题。它目前在一个应用程序中使用,目的是避免重写所有内容。

谢谢!

3 个答案:

答案 0 :(得分:3)

这已在MySQL 5.1.17中修复,以允许CURDATE()在DATE列中存储时评估为小于NOW()。

现在,在将DATE与DATETIME进行比较时,它们将被比较为DATETIME。当DATE被投射到DATETIME时,它有一个零小时。

如果my_date_field'2010-01-01'NOW()'2010-01-01 05:01:01',则在比较时,my_date_field会提升为'2010-01-01 00:00:00',这显然是'2010-01-01 05:01:01'小于{{1}}。

最初,当左侧是一列时,从DATE到DATETIME的促销没有发生。然而,显然他们认为总是推广它更加一致。

抱歉,但你很幸运,之前有用过。具有零小时的日期应评估为小于非零小时的相同日期。

不幸的是,没有办法关闭这个“错误修复”。您唯一的解决方案是将NOW()更改为CURDATE()或回滚到先前版本。

实际上,您可以编译自己的版本并撤消“错误修复”或覆盖NOW()函数。

答案 1 :(得分:1)

行为是有道理的,因为NOW()属于DATETIME类型,CURDATE()类型为DATE

至于为什么变量是在一个服务器版本中而不是在另一个服务器版本中强制转换的 - 这听起来更像是server modes中的差异,即转换失败比另一个更严格的一个实例。 / p>

该文件中有趣的一点(不确定这是否是您的问题,但可能是这样):ALLOW_INVALID_DATES

  

此模式在MySQL 5.0.2中实现。在5.0.2之前,这是默认的MySQL日期处理模式。从5.0.2开始,服务器要求月和日值合法,而不仅仅分别在1到12和1到31的范围内。禁用严格模式后,“2004-04-31”等无效日期将转换为“0000-00-00”,并生成警告。启用严格模式后,无效日期会生成错误。要允许此类日期,请启用ALLOW_INVALID_DATES。

无论如何,我不确定是否有必要通过更改日志来试图找出什么时候发生了变化。我倾向于使这些行为在两种情况下都有效(例如,如果我理解正确,请使用CURDATE())并完成它。

答案 2 :(得分:0)

仅比较日期时间列的日期部分:

SELECT * FROM my_table WHERE DATE(my_date_field) = DATE(NOW())