web-dev-qa-db-ja.com

ER_TRUNCATED_WRONG_VALUE:不正な日時値

だから私は最近、研究プロジェクトの申請を完了しました。それはすべて良好で、私が残したのはアプリケーションを本番環境に置くことだけです。

私は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'_が突然有効な日付形式にならないのはなぜですか?どうすれば修正できますか?

助けてくれてありがとう!

11
Jesper

どうやら、datetime値は有効な 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)
13
Jesper

同じ答え(@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';
1