【问题标题】:STR_TO_DATE discrepancy between MySQL 5.5 and MySQL 5.6MySQL 5.5 和 MySQL 5.6 之间的 STR_TO_DATE 差异
【发布时间】:2016-04-22 06:41:21
【问题描述】:

此 SQL 在 MySQL 5.5 中返回 DATE,但在 MySQL 5.6 中返回 NULL。为什么?

select date(STR_TO_DATE('2015-01', '%Y-%m')) + INTERVAL 1 DAY;

这是 MySQL 5.55.6 的 SQL Fiddle。 STR_TO_DATE 在这两种情况下都返回一个日期。使用DATE 转换结果有效。尝试添加INTERVAL 时出现问题。我在STR_TO_DATE(...)DATE(STR_TO_DATE(...)) 上加一个INTERVAL 都没有关系,结果是一样的。但是,删除 STR_TO_DATE 即可。

select
    STR_TO_DATE('2015-01', '%Y-%m') as same_a1,
    STR_TO_DATE('2015-01-01', '%Y-%m') as same_a2,
    STR_TO_DATE('2015-01', '%Y-%m-%d') as same_a3,
    STR_TO_DATE('2015-01-01', '%Y-%m-%d') as same_a4,
    date(STR_TO_DATE('2015-01', '%Y-%m')) as same_b1,
    date(STR_TO_DATE('2015-01-01', '%Y-%m')) as same_b2,
    date(STR_TO_DATE('2015-01', '%Y-%m-%d')) as same_b3,
    date(STR_TO_DATE('2015-01-01', '%Y-%m-%d')) as same_b4,
    STR_TO_DATE('2015-01', '%Y-%m') + INTERVAL 1 DAY as same_c1,
    STR_TO_DATE('2015-01-01', '%Y-%m') + INTERVAL 1 DAY as same_c2,
    STR_TO_DATE('2015-01', '%Y-%m-%d') + INTERVAL 1 DAY as same_c3,
    STR_TO_DATE('2015-01-01', '%Y-%m-%d') + INTERVAL 1 DAY as same_c4,
    date(STR_TO_DATE('2015-01', '%Y-%m')) + INTERVAL 1 DAY as different_d1,
    date(STR_TO_DATE('2015-01-01', '%Y-%m')) + INTERVAL 1 DAY as different_d2,
    date(STR_TO_DATE('2015-01', '%Y-%m-%d')) + INTERVAL 1 DAY as different_d3,
    date(STR_TO_DATE('2015-01-01', '%Y-%m-%d')) + INTERVAL 1 DAY as same_d4,
    date('2015-01') + INTERVAL 1 DAY as same_e1,
    date('2015-01-01') + INTERVAL 1 DAY as same_e2
;

我搜索了发行说明,但找不到任何东西。到底是怎么回事?这是已知的变化吗?一个错误?

【问题讨论】:

  • 对于它的价值,我发现 5.1.73 和 MariaDB 10.0.21 之间存在相同的差异。
  • 使用 MySQL CLI 客户端而不是 SQLFiddle,我看到 STR_TO_DATE() 在没有给出日期值时会产生奇怪的结果:SELECT STR_TO_DATE('2015-03') 会产生 2015-03-00。我无法添加日期。它在旧版本和新版本中都产生“第 00 天”的事实一开始似乎是错误的,但是考虑到奇怪的行为,如果在以后的版本中没有收到 NULL,就无法在该无效日期上添加间隔这一事实似乎是正确的。旧版本允许我将 1 天添加到“第 00 天”,如 SELECT DATE(STR_TO_DATE('2015-03', '%Y-%m')) + INTERVAL 1 DAY; 导致 2015-03-01
  • ^^... 这不是我所期望的结果。我希望它从 2015-03-01 开始并添加 1 天导致 2015-03-02
  • 我发现一些博客文章提到了支持的 00 天或 00 月值,但除了众所周知的零日期 0000-00-00 00:00:00 之外没有官方文档。
  • @MichaelBerkowski: "NO_ZERO_IN_DATE 模式影响服务器是否允许年部分为非零但月或日部分为 0 的日期。"

标签: mysql sql str-to-date


【解决方案1】:

这是一个已知的变化,它在不经意间被引入到版本 5.1.595.5.165.6.3 中(但随后在版本 5.1.625.5.21 中回滚;它保留在 5.6 行中):

不兼容的更改:修改了与日期相关的断言的处理。

但是,此更改的结果是,当将 DATE() 函数值作为参数传递并拒绝日期部分为零的不完整日期时,一些函数变得更加严格。这些功能受到影响:CONVERT_TZ()DATE_ADD()DATE_SUB()DAYOFYEAR()LAST_DAY()TIMESTAMPDIFF()TO_DAYS()TO_SECONDS()WEEK()WEEKOFYEAR()WEEKOFYEAR()、@3 987654338@。因为这改变了通用可用性状态系列(MySQL 5.1 和 5.5)中的日期处理行为,所以它在 5.1.62 和 5.5.21 中被恢复。 MySQL 5.6 中保留了更改。

参考:另见错误 #13458237。

您会受到影响,因为 + INTERVAL 符号只是 DATE_ADD() 函数周围的语法糖。

【讨论】:

  • 顺便说一下,在 5.6 行中的更改仅用于 LAST_DAY()5.6.5
  • +1 谢谢@eggyal!这正是我一直在寻找的。现在我可以证明问题不是由我的代码引起的。
猜你喜欢
  • 2014-03-21
  • 1970-01-01
  • 1970-01-01
  • 2011-01-23
  • 1970-01-01
  • 2018-07-24
  • 1970-01-01
  • 2020-09-12
  • 2013-08-07
相关资源
最近更新 更多