ER_TRUNCATED_WRONG_VALUE:不正确的日期时间值

Posted

技术标签:

【中文标题】ER_TRUNCATED_WRONG_VALUE:不正确的日期时间值【英文标题】:ER_TRUNCATED_WRONG_VALUE: Incorrect datetime value 【发布时间】:2017-11-02 10:32:51 【问题描述】:

所以我最近完成了一项研究项目的申请。一切都很好,我剩下的就是将应用程序投入生产。

我将 mysql 与 Node.js 一起使用(我知道,我们不喜欢那样,但有人必须尝试一下)。我有一个将聊天消息添加到 mysql 消息表的套接字,其中包含文本、日期时间等。日期时间设置为 new Date()

现在当我将应用程序放在生产服务器中(重新安装依赖项,mysql 等)时,我在写消息时突然收到此错误:

Error: ER_TRUNCATED_WRONG_VALUE: Incorrect datetime value: '2017-06-01T09:45:06.253Z' for column 'message_datetime' at row 1

我在开发过程中没有遇到那个错误,所以我问自己是否下载了不同版本的 mysql... 我做了:

发展:

mysql  Ver 14.14 Distrib 5.5.54, for debian-linux-gnu (i686) using readline 6.3

生产

mysql Ver 14.14 Distrib 5.7.18, for Linux (x86_64) using EditLine wrapper

消息表如下所示:

CREATE TABLE message ( message_id INT AUTO_INCREMENT, message_sender_id VARCHAR(80) NOT NULL, message_datetime DATETIME, message_text TEXT, message_chat_id INT NOT NULL, PRIMARY KEY(message_id), FOREIGN KEY(message_chat_id) REFERENCES chat(id) ON DELETE CASCADE ) ENGINE=InnoDB;

那么有什么区别呢?为什么'yyyy-mm-ddThh:mm:ss.%%%Z' 突然不是有效的日期格式?我该如何解决?

感谢您的帮助!

【问题讨论】:

dev.mysql.com/doc/refman/5.7/en/datetime.html: "MySQL 以 'YYYY-MM-DD HH:MM:SS' 格式检索和显示 DATETIME 值。支持的范围是 '1000-01-01 00:00 :00' 到 '9999-12-31 23:59:59'。" “我在开发中没有遇到那个错误” - 这可能更多是服务器配置问题(关于容错),而不是它实际工作和插入 有效日期到数据库中。 @CBroe 我什至不知道有不同的容错能力。我在我的开发环境中使用了 vagrant,但将生产服务器放在了数字海洋上。也许生产服务器中的某种更新会降低容错能力 感谢您发布此问题。我曾想象自己发布了一个类似的问题,关于 javascript/Angular 中的“Z”被 MySQL 拒绝,并且也让自己说“(我知道,我们不喜欢它,但有人必须尝试一下。)” .很高兴看到它也在那里。 :) 【参考方案1】:

显然,日期时间值不是有效的MySQL Datetime。但是有一个修改Server SQL Modes的工作。

由于某种原因,在我的开发服务器中,MySQL 默认模式配置被完全删除。因此对于如何插入日期时间没有任何限制。

mysql> select @@sql_mode;
    +------------+
    | @@sql_mode |
    +------------+
    |            |
    +------------+
    1 row in set (0.00 sec)

另一方面,在生产服务器上,有大量限制告诉 mysql 服务器接受哪种日期时间格式。

mysql> select @@sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@sql_mode                                                                                                                                |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+

这不是一个安全的方法,但我将 MySQL 限制模式更改为no_engine_substitution,瞧,一切都像魅力一样(几乎)。您必须更改 GLOBAL 和 SESSION 模式才能使其正常工作。

标准 SQL 模式是“NO_ENGINE_SUBSTITUTION”,因此我们将使用该模式。您可以添加更多模式:

SET GLOBAL sql_mode = '<mode>';
SET SESSION sql_mode = '<mode>';

现在应该将 GLOBAL 和 SESSION 模式设置为 NO_ENGINE_SUBSTITUTION

mysql> SET SESSION sql_mode = 'NO_ENGINE_SUBSTITUTION';
mysql> SELECT @@SESSION.sql_mode;
+------------------------+
| @@SESSION.sql_mode     |
+------------------------+
| NO_ENGINE_SUBSTITUTION |
+------------------------+
1 row in set (0.00 sec)

mysql> SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION';
mysql> SELECT @@GLOBAL.sql_mode;
+------------------------+
| @@GLOBAL.sql_mode      |
+------------------------+
| NO_ENGINE_SUBSTITUTION |
+------------------------+
1 row in set (0.00 sec)

【讨论】:

您应该接受您的回答以表明您已经找到了解决方案。 @RobG 好吧,我得等 1 天 4 小时才能做到这一点 @Jesper 看起来你这里有一个小错字。第二个命令应该是mysql&gt; SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION'; 我遇到了和你一样的问题,但我还必须在 sql_mode 中添加 ALLOW_INVALID_DATES 才能使我的应用程序正常工作。但是:虽然 MySQL 清楚地检测到给定的日期是无效的,但正确存储它们没有问题...... @Scorpioo590 如何在他们的 MySQL 上使用 ALLOW_INVALID_DATES?【参考方案2】:

相同的答案(由@Jesper 给出)适用于错误

ERROR 1292 (22007): Truncated incorrect DOUBLE value: ''

即我的

select @@GLOBAL.sql_mode; -- and
select @@SESSION.sql_mode;

给了

STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

当我将它们更新为

SET SESSION sql_mode = 'NO_ENGINE_SUBSTITUTION';
SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION';

我的 SQL 插入执行没有故障

这个错误是因为严格的 SQL 模式。所以只从 sql_mode 中删除 STRICT_TRANS_TABLES 就足够了。例如

SET SESSION sql_mode = 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

【讨论】:

感谢这对我使用 knex 从 sqlite 到 mysql 导出到 json 有用,我添加了这个 knex.raw() ``` js knex.raw(SET SESSION sql_mode = 'NO_ENGINE_SUBSTITUTION'; SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION';); ```

以上是关于ER_TRUNCATED_WRONG_VALUE:不正确的日期时间值的主要内容,如果未能解决你的问题,请参考以下文章