web-dev-qa-db-fra.com

Erreur dans mysql lors de la définition de la valeur par défaut pour DATE ou DATETIME

J'utilise MySql Server 5.7.11 et cette phrase:

updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00'

est not travaille. Donner l'erreur:

ERROR 1067 (42000): Invalid default value for 'updated'

Mais ce qui suit:

updated datetime NOT NULL DEFAULT '1000-01-01 00:00:00'

fonctionne simplement .

Même cas pour DATE.

En tant que sidenote _, il est mentionné dans la mysql docs :

Le type DATE est utilisé pour les valeurs avec une partie date, mais aucune partie heure. MySQL récupère et affiche les valeurs DATE au format 'AAAA-MM-JJ'. La plage prise en charge est «1000-01-01» à «9999-12-31».

même s'ils disent aussi:

Les valeurs DATE, DATETIME ou TIMESTAMP non valides sont converties en la valeur "zéro" du type approprié ("0000-00-00" ou "0000-00-00 00:00:00").

Ayant également pris en compte la deuxième citation de la documentation mysql, est-ce que quelqu'un pourrait me dire pourquoi il donne cette erreur?

76
Evhz

L'erreur est due au mode SQL qui peut être strict selon la dernière documentation MYSQL 5.7

La documentation MySQL 5.7 dit :

Le mode strict détermine si le serveur autorise "0000-00-00" comme date valide: Si le mode strict n'est pas activé, '0000-00-00' est autorisé et les insertions ne produisent aucun avertissement . Si le mode strict est activé, '0000-00-00' n'est pas autorisé et les insertions génèrent une erreur, sauf si IGNORE est également indiqué. Pour INSERT IGNORE et UPDATE IGNORE, '0000-00-00' est autorisé et les insertions génèrent un avertissement.

Pour vérifier le mode MYSQL

SELECT @@GLOBAL.sql_mode global, @@SESSION.sql_mode session

Désactivation du mode STRICT_TRANS_TABLES

Cependant, pour autoriser le format 0000-00-00 00:00:00vous devez désactiver le mode STRICT_TRANS_TABLES dans le fichier de configuration mysql ou par commande.

Par commande

SET sql_mode = '';

ou

SET GLOBAL sql_mode = '';

L’utilisation du mot clé GLOBAL requiert des super previliges et affecte les opérations auxquelles tous les clients se connectent à partir de ce moment.

si ci-dessus ne fonctionne pas, allez à /etc/mysql/my.cnf (comme dans Ubuntu) et commentez STRICT_TRANS_TABLES

De même, si vous souhaitez définir de manière permanente le mode SQL au démarrage du serveur, incluez SET sql_mode='' dans my.cnf sous Linux ou MacOS. Pour Windows, cela doit être fait dans le fichier my.ini.

Remarque

Cependant, le mode strict n'est pas activé par défaut dans MYSQL 5.6. Par conséquent, cela ne produit pas l'erreur selon la documentation MYSQL 6 qui dit

MySQL vous permet de stocker une valeur «zéro» de «0000-00-00» en tant que «date fictive». Dans certains cas, cela est plus pratique que d'utiliser des valeurs NULL et utilise moins de données et d'espace d'index. Pour interdire "0000-00-00", activez le mode SQL NO_ZERO_DATE. 

METTRE À JOUR

En ce qui concerne le problème de bug comme l'a dit @ Dylan-Su:

Je ne pense pas que ce soit le bogue de la façon dont MYSQL a évolué au fil du temps, en raison de certaines modifications qui ont été apportées en fonction des améliorations ultérieures apportées au produit.

Cependant, j'ai un autre rapport de bogue lié à la fonction NOW() 

Le champ date/heure n'accepte pas la valeur par défaut NOW ()

Une autre note utile [voir Initialisation et mise à jour automatiques pour TIMESTAMP et DATETIME ]

Depuis MySQL 5.6.5, les colonnes TIMESTAMP et DATETIME peuvent être automatiquement initialisées et mises à jour avec la date et l'heure actuelles (c'est-à-dire l'horodatage actuel). Avant la version 5.6.5, cela n’est vrai que pour TIMESTAMP et pour au plus une colonne TIMESTAMP par table. Les notes suivantes décrivent d’abord l’initialisation et la mise à jour automatiques de MySQL 5.6.5 et versions ultérieures, puis les différences entre les versions précédentes 5.6.5. 

Mise à jour concernant NO_ZERO_DATE

À partir de la version 5.7.4 de MySQL, ce mode est obsolète. Pour la version précédente, vous devez commenter la ligne correspondante dans le fichier de configuration. Reportez-vous à documentation MySQL 5.7 sur NO_ZERO_DATE

143
geeksal

J'ai eu cette erreur avec WAMP 3.0.6 avec MySQL 5.7.14.

Solution

changer la ligne 70 (si votre fichier ini est intact) dans le fichier c:\wamp\bin\mysql\mysql5.7.14\my.ini à partir de 

sql-mode= "STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER"

à

sql-mode="ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER"

et redémarrez tous les services.

Cela désactivera le mode strict. Selon la documentation, «mode strict» signifie un mode avec l'un ou l'autre ou les deux STRICT_TRANS_TABLES ou STRICT_ALL_TABLES activé . La documentation dit:

"Le mode SQL par défaut dans MySQL 5.7 inclut les modes suivants:

14
bg17aw

Problème de syntaxe de configuration

Sur certaines versions de MYSQL (testé 5.7. *) Sous les systèmes * nix, vous devez utiliser cette syntaxe:

[mysqld]

sql-mode="NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLE,NO_ENGINE_SUBSTITUTION"

Ceux-ci ne fonctionneront pas:

tiret sans guillemets

sql-mode=NO_ENGINE_SUBSTITUTION

soulignement pas de guillemets

sql_mode=NO_ENGINE_SUBSTITUTION

trait de soulignement et guillemets

sql_mode="NO_ENGINE_SUBSTITUTION"

Un examen plus complet des valeurs de configuration et du mode SQL:

Comment configurer les indicateurs permanents du mode SQL -

4
Heroselohim

Ajoutez simplement la ligne: sql_mode = "NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

fichier intérieur: /etc/mysql/mysql.conf.d/mysqld.cnf

alors Sudo service mysql restart

4
ferreidon aftahi

Je me suis trouvé dans une situation où les données étaient mélangées entre NULL et 0000-00-00 pour un champ de date. Mais je ne savais pas comment mettre à jour le '0000-00-00' vers NULL, car 

 update my_table set my_date_field=NULL where my_date_field='0000-00-00'

n'est plus autorisé .. .. Ma solution de contournement était assez simple:

update my_table set my_date_field=NULL where my_date_field<'1000-01-01'

parce que toutes les valeurs my_date_field incorrectes (que les dates soient correctes ou non) étaient antérieures à cette date.

2
Martin T.

Cela fonctionne pour 5.7.8:

mysql> create table t1(updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00');
Query OK, 0 rows affected (0.01 sec)

mysql> show create table t1;
+-------+-------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                            |
+-------+-------------------------------------------------------------------------------------------------------------------------+
| t1    | CREATE TABLE `t1` (
  `updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-------+-------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.8-rc  |
+-----------+
1 row in set (0.00 sec)

Vous pouvez créer un SQLFiddle pour recréer votre problème. 

http://sqlfiddle.com/

Si cela fonctionne pour MySQL 5.6 et 5.7.8, mais échoue le 5.7.11. Ce sera probablement un bug de régression pour 5.7.11.

2
Dylan Su

Commencez par sélectionner la session en cours sql_mode:

SELECT @@SESSION.sql_mode;

Ensuite, vous obtiendrez quelque chose comme ça valeur par défaut :

'ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USATE, NO_ENGINE_SUBSTITUTION'

puis définissez sql_mode sans 'NO_ZERO_DATE':

SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

Si vous avez des subventions, vous pouvez également le faire pour GLOBAL:

SELECT @@GLOBAL.sql_mode;
SET GLOBAL sql_mode = '...';
2
simhumileco

Cette réponse ne concerne que MySQL 5.7:

Le meilleur n'est pas vraiment défini dans le sql_mode vide, utilisez plutôt dans PHP une variable de session avec:

SET SESSION sql_mode= 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

Donc, au moins, vous conservez les autres valeurs par défaut.

C'est fou que la documentation de mysql ne soit pas claire, vous devez supprimer ces valeurs par défaut dans sql_mode:

NO_ZERO_IN_DATE, NO_ZERO_DATE, je comprends, mais dans les versions futures, cela sera abandonné.

STRICT_ALL_TABLES, avec cela, avant que les paramètres ne soient ignorés, vous devez donc le supprimer également.

Enfin, la documentation parle de ce paramètre: "donnez une erreur au lieu d'un avertissement" lors de l'insertion d'une valeur incorrecte dans une colonne ", avec ce paramètre, les dates avec des valeurs nulles ne sont pas insérées, mais sans oui.

MySQL n'est pas vraiment organisé avec ces paramètres et combinaisons.

1
stackdave
set global sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
0
Aris tri jaka

Pour résoudre le problème avec MySQL Workbench (après l’application de la solution côté serveur):

Supprimez SQL_MODE en TRADITIONAL dans le panneau des préférences.

 enter image description here

0
Vindic

Combinaisons d’options pour mysql Ver 14.14 Distrib 5.7.18, for Linux (x86_64).

Ne jette pas:

STRICT_TRANS_TABLES + NO_ZERO_DATE

Jette:

STRICT_TRANS_TABLES + NO_ZERO_IN_DATE

Mes paramètres dans /etc/mysql/my.cnf sur Ubuntu:

[mysqld]
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
0
Green