web-dev-qa-db-fra.com

Pourquoi une colonne de texte ne peut-elle pas avoir une valeur par défaut dans MySQL?

Si vous essayez de créer une colonne TEXT sur une table et que vous lui attribuez une valeur par défaut dans MySQL, vous obtenez une erreur (au moins sous Windows). Je ne vois aucune raison pour laquelle une colonne de texte ne devrait pas avoir une valeur par défaut. Aucune explication n’est donnée par la documentation MySQL. Cela me semble illogique (et quelque peu frustrant, car je veux une valeur par défaut!). Quelqu'un sait pourquoi ce n'est pas permis?

159
Russ

Windows MySQL v5 génère une erreur, mais Linux et les autres versions ne font qu'émettre un avertissement. Cela doit être corrigé. WTF?

Voir aussi une tentative de résolution de ce problème sous le bogue n ° 19498 dans le bugtracker de MySQL:

Bryce Nesbitt le 4 avril 2008 à 16h36:
Sous MS Windows, la règle "pas de DEFAUT" est une erreur, alors que sur d’autres plates-formes, il s’agit souvent d’un avertissement. Bien qu’il ne s’agisse pas d’un bogue, il est possible d’être piégé par cela si vous écrivez du code sur une plate-forme clémente, puis l’exécutez sur une plate-forme stricte:

Personnellement, je considère cela comme un bug. La recherche de "colonne BLOB/TEXT ne pouvant pas avoir de valeur par défaut" renvoie environ 2 940 résultats sur Google. La plupart d'entre eux sont des rapports d'incompatibilités lors de la tentative d'installation de scripts de base de données fonctionnant sur un système mais pas sur d'autres.

Je rencontre maintenant le même problème avec une application Web que je modifie pour l'un de mes clients, initialement déployé sur Linux MySQL v5.0.83-log. J'utilise Windows MySQL v5.1.41. Même en essayant d'utiliser la dernière version de phpMyAdmin pour extraire la base de données, cela ne signale pas de valeur par défaut pour la colonne de texte en question. Cependant, lorsque j'essaie d'exécuter une insertion sous Windows (qui fonctionne correctement sous Linux), je reçois une erreur sans défaut sur la colonne ABC. J'essaie de recréer la table localement avec la valeur par défaut évidente (en fonction d'une sélection de valeurs uniques pour cette colonne) et finis par recevoir la colonne oh-so-utile La colonne BLOB/TEXT ne peut pas avoir de valeur par défaut.

Encore une fois, ne pas maintenir la compatibilité de base sur toutes les plates-formes est inacceptable et constitue un bogue.


Comment désactiver le mode strict dans MySQL 5 (Windows):

  • Éditez /my.ini et cherchez la ligne

    sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
    
  • Le remplacer par

    sql_mode='MYSQL40'
    
  • Redémarrez le service MySQL (en supposant qu'il s'agisse de mysql5)

    net stop mysql5
    net start mysql5
    

Si vous avez un accès root/admin, vous pourrez peut-être exécuter

mysql_query("SET @@global.sql_mode='MYSQL40'");
82
Ku Logix

Sans une connaissance approfondie du moteur MySQL, je dirais que cela ressemble à une stratégie de sauvegarde de la mémoire. Je suppose que la raison est derrière ce paragraphe de la docs :

Chaque valeur BLOB ou TEXT est représentée en interne par un objet alloué séparément. Cela contraste avec tous les autres types de données, pour lesquels le stockage est alloué une fois par colonne lors de l'ouverture de la table.

Il semble que le pré-remplissage de ces types de colonnes entraîne une utilisation de la mémoire et des performances réduites.

26
Pekka 웃

Vous pouvez obtenir le même effet qu'une valeur par défaut en utilisant un déclencheur

create table my_text

(
   abc text
);

delimiter //
create trigger mytext_trigger before insert on my_text
for each row
begin
   if (NEW.abc is null ) then
      set NEW.abc = 'default text';
   end if;
end
//
delimiter ;
14
Tim Child

"Prise en charge de DEFAULT dans les colonnes TEXT/BLOB" est une demande de fonctionnalité dans le bugtracker MySQL (bogue n ° 21532) .

Je vois que je ne suis pas le seul à vouloir mettre une valeur par défaut dans une colonne TEXT. Je pense que cette fonctionnalité devrait être supportée dans une version ultérieure de MySQL.

Cela ne peut pas être corrigé dans la version 5.0 de MySQL, car cela causerait apparemment une incompatibilité et une perte de données si quelqu'un essayait de transférer une base de données entre les bases de données (actuelles) qui ne prennent pas en charge cette fonctionnalité et celles qui le supportaient. cette fonctionnalité.

9
David Cary

Comme la question principale:

Quelqu'un sait pourquoi ce n'est pas permis?

n’a toujours pas obtenu de réponse, j’ai fait une recherche rapide et trouvé un ajout relativement nouveau d’un développeur MySQL à MySQL Bugs :

[17 mars 2017 15:11] Ståle Deraas

Publié par développeur:

Il s'agit en effet d'une demande de fonctionnalité valide, et à première vue, il pourrait sembler trivial d'ajouter. Mais les valeurs TEXT/BLOBS ne sont pas stockées directement dans le tampon d’enregistrement utilisé pour la lecture/mise à jour des tables. Il est donc un peu plus complexe de leur attribuer des valeurs par défaut.

Ce n'est pas une réponse définitive, mais au moins un point de départ pour la question pourquoi .

En attendant, je vais simplement coder tout autour et rendre la colonne nullable ou assigner explicitement un (default '') valeur pour chaque insert du code de l'application ...

6
Marten Koetsier

Je gère normalement des sites sur Linux, mais je développe également sur une machine Windows locale. J'ai rencontré ce problème à plusieurs reprises et j'ai juste corrigé les tables lorsque j'ai rencontré le problème. J'ai installé une application hier pour aider quelqu'un et j'ai bien sûr rencontré le problème à nouveau. J'ai donc décidé qu'il était temps de comprendre ce qui se passait - et j'ai trouvé ce fil. Je n'aime vraiment pas l'idée de changer le mode sql_mode du serveur à un mode antérieur (par défaut), alors j'ai proposé une solution simple (à mon avis).

Bien entendu, cette solution obligerait les développeurs à envelopper leurs scripts de création de table pour compenser le problème de MySQL sous Windows. Vous verrez des concepts similaires dans les fichiers de vidage. Un gros bémol est que cela pourrait/va causer des problèmes si le partitionnement est utilisé.

// Store the current sql_mode
mysql_query("set @orig_mode = @@global.sql_mode");

// Set sql_mode to one that won't trigger errors...
mysql_query('set @@global.sql_mode = "MYSQL40"');

/**
 * Do table creations here...
 */

// Change it back to original sql_mode
mysql_query('set @@global.sql_mode = @orig_mode');

C'est à peu près ça.

6
Darrell Greenhouse

Pour Ubuntu 16.04:

Comment désactiver le mode strict dans MySQL 5.7:

Editez le fichier /etc/mysql/mysql.conf.d/mysqld.cnf

Si la ligne ci-dessous existe dans mysql.cnf

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

Puis remplacez-le par

sql_mode='MYSQL40'

Autrement

Ajoutez juste la ligne ci-dessous dans mysqld.cnf

sql_mode='MYSQL40'

Ce problème résolu.

1
ShivBuyya