6

我的表中有一些无效日期。我听说我可以禁用严格模式或使用不起作用的 sql_mode ALLOW_INVALID_DATES(已通过选择 @@global.sql_mode 确认并重新启动服务器)。

我的问题是,我不能修复这些“无效”日期吗?我将无法在每台服务器上禁用严格模式。

select * from table
>> Mysql2::Error: Invalid date: 1900-00-00

mysql --version
mysql  Ver 14.14 Distrib 5.1.61, for debian-linux-gnu (i686) using readline 6.1

mysql> select @@global.sql_mode;
+---------------------+
| @@global.sql_mode   |
+---------------------+
| ALLOW_INVALID_DATES |
4

1 回答 1

7

看起来您的错误消息来自您的 MySQL 客户端,而不是服务器。因此,设置服务器严格模式不会帮助您使用此客户端显示这些日期。

您的数据中似乎有一些 2012-09-31 或 2013-02-29 样式的日期。它们的格式正确,但其他方面是错误的。在 MySQL 的 5.0.2 之前的版本中,这些没有被正确地捕获到您的数据中。现在,您的服务器设置ALLOW_INVALID_DATES为不会对它们作呕,而是将它们转换为“0000-00-00”。客户正在嘲笑他们。

清理它的第一步是识别有问题的行。你可以试试这个。

首先,开启ALLOW_INVALID_DATES

然后,运行此查询以查看您的表。不要使用SELECT *

  SELECT col,col,col,DATE_FORMAT(datecol,'%Y-%m-%d') 
    FROM mytable
   ORDER BY DATE_FORMAT(datecol,'%Y-%m-%d') 

尝试从结果集中找出哪些日期是垃圾。它们可能会放在此 select 语句中的第一个位置,但您将不得不费力地寻找它们。

接下来,弄清楚你想如何修复它们。删除行?将日期更改为 1941-12-07(臭名昭著的日期)?我们无法告诉您您需要在这里做什么。

然后,修复它们。如果只有一两个,就一个一个修复。

  UPDATE mytable
     SET datecol='whatever replacement date'
   WHERE id='the id of the offending row.'

或者

  DELETE FROM mytable
        WHERE id='the id of the offending row.'

如果有数千个,你可以用这样的东西批量修复它们。但是,如果没有首先在测试服务器上非常仔细地解决问题,请不要这样做。如果你犯了一个错误,你会毁了你的桌子。

  UPDATE mytable
     SET datecol='whatever replacement date'
   WHERE '0000-00-00' = DATE_FORMAT(datecol,'%Y-%m-%d')

在你纠正完你的问题后,回去做你的SELECT *,以确保你得到了所有的问题。

然后禁用ALLOW_INVALID_DATES并且永远不再重新启用它。

那应该收拾烂摊子。请注意,现实世界的数据总是有些行并不完美。

于 2012-10-17T12:56:31.427 回答