1

我对 MySQL 5.1 有疑问。datetime 数据类型不会隐式转换为匹配日期列。

 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。

该问题仅出现在从日期时间到日期的隐式转换中。没有人已经遇到过这个问题或知道如何解决这个问题吗?我知道使用 NOW() 而不是 CURTIME() 不是最好的,但这不是这里的问题。它目前在应用程序中使用,目的是避免重写所有内容。

谢谢!

4

3 回答 3

3

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

现在,当将 DATE 与 DATETIME 进行比较时,它们将作为 DATETIME 进行比较。当 DATE 转换为 DATETIME 时,它的小时数为零。

If my_date_fieldis '2010-01-01'AND NOW()is '2010-01-01 05:01:01',当它们比较时,my_date_field提升为'2010-01-01 00:00:00',这显然小于'2010-01-01 05:01:01'

原来,当左侧是一列时,没有发生从 DATE 到 DATETIME 的提升。然而,显然他们认为总是推广它更一致。

对不起,但你很幸运,它以前工作过。具有零小时的日期的计算结果应小于具有非零小时的相同日期。

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

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

于 2010-04-27T18:21:10.873 回答
1

这种行为是有意义的,因为NOW()它属于 type DATETIME,并且CURDATE()属于 type DATE

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

该文档中的一个有趣点(不确定这是否是您的问题,但可能是):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())并完成它。

于 2010-04-27T17:29:38.613 回答
0

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

SELECT * FROM my_table WHERE DATE(my_date_field) = DATE(NOW())
于 2010-04-27T17:31:45.047 回答