MySQL 5.6 DateTime Valeur datetime incorrecte: '2013-08-25T17: 00: 00 + 00: 00' avec le code d'erreur 1292

15

J'utilise MySQL 5.6 et j'ai un programme qui exécute l'instruction SQL suivante sur ma base de données:

UPDATE `m_table` SET `s_time` = '2013-08-25T17:00:00+00:00' WHERE id = '123' 

Malheureusement, j'obtiens l'erreur suivante: Valeur datetime incorrecte: '2013-08-25T17: 00: 00 + 00: 00' pour la colonne 's_time' à la ligne 1

Le type de données pour s_time est DateTime.

J'ai déjà tenté de définir la propriété allow_invalid_dates à l'aide du plan de travail.

Quelqu'un peut-il comprendre et s'il vous plaît m'expliquer cette erreur? Je sais que si je change manuellement l'instruction en UPDATE m_tableSET s_time= '2013-08-25 17:00:00' WHERE id = '123', l'instruction fonctionne.

Malheureusement, je ne peux pas modifier le programme qui fournit l'instruction SQL (dont le créateur du programme me dit qu'il est valide) et je ne comprends pas non plus ce que symbolise +00: 00.

Merci

Andrew
la source

Réponses:

24
'2013-08-25T17:00:00+00:00'

C'est une valeur datetime iso-8601 valide , mais ce n'est pas un littéral datetime MySQL valide . Sur ce point, le développeur est incorrect.

La documentation explique ce que ALLOW_INVALID_DATESfait:

Vérifiez seulement que le mois est compris entre 1 et 12 et que le jour est compris entre 1 et 31.

En d'autres termes, 2013-02-31serait une date autorisée si elle allow_invalid_datesest définie. Cette option ne fait rien lorsque la date ou datetime n'est même pas dans un format valide pour MySQL.

Le +00:00est le décalage horaire de UTC . Dans ce cas, le temps exprimé est en UTC, donc le décalage est zéro heure, zéro minute.

Votre solution serait de supprimer le STRICT_TRANS_TABLESdu sql_modequi est un défaut dans le fichier de configuration créé pendant le processus d'installation MySQL 5.6 ... vous devez examiner attentivement les conséquences de l' évolution, mais elle ne permet aux données d'entrer.

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

mysql> insert into datetimetest(dt) values ('2013-08-26T12:00:00+00:00');
ERROR 1292 (22007): Incorrect datetime value: '2013-08-26T12:00:00+00:00' for column 'dt' at row 1

-- remove STRICT_TRANS_TABLES -- note that executing this only removes it for your
-- current session -- it does not make a server-wide config change

mysql> set @@sql_mode='no_engine_substitution';
Query OK, 0 rows affected (0.00 sec)

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

-- now MySQL will accept the invalid value, with a warning

mysql> insert into datetimetest(dt) values ('2013-08-26T12:00:00+00:00');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> show warnings;
+---------+------+-----------------------------------------+
| Level   | Code | Message                                 |
+---------+------+-----------------------------------------+
| Warning | 1265 | Data truncated for column 'dt' at row 1 |
+---------+------+-----------------------------------------+
1 row in set (0.00 sec)

-- the value did get inserted, but the time zone information was lost:

mysql> select * from datetimetest;
+----+---------------------+
| id | dt                  |
+----+---------------------+
|  1 | 2013-08-26 12:00:00 |
+----+---------------------+
1 row in set (0.00 sec)
Michael - sqlbot
la source
Je vous remercie. À la fin, j'ai demandé au programmeur de changer le code PHP qui a créé l'instruction SQL pour répondre à la norme MySQL, mais c'est une solution de contournement intéressante. Ce qui est étrange, c'est que l'instruction SQL d'origine fonctionne dans les anciennes versions de MySQL.
Andrew
2
L'inclusion STRICT_TRANS_TABLESdans un fichier de configuration par défaut n'a été introduite que dans MySQL 5.6, ce qui explique le changement de comportement ... si vous l'activez SQL_MODEdans les versions précédentes, la requête se briserait également dans ces versions.
Michael - sqlbot
Tu viens de me sauver la vie. Merci beaucoup pour la réponse!
rafaels88