2009-10-01 8 views
104

Le manuel de référence MySQL ne fournit pas d'exemple clair sur la façon de procéder.Comment ajouter plus de membres à ma colonne de type ENUM dans MySQL?

J'ai une colonne de type ENUM dans laquelle je dois ajouter plus de pays. Quelle est la bonne syntaxe MySQL pour y parvenir?

Voilà ma tentative:

ALTER TABLE carmake CHANGE country country ENUM('Sweden','Malaysia'); 

L'erreur que je reçois est: ERROR 1265 (01000): Data truncated for column 'country' at row 1.

La colonne country est la colonne de type ENUM dans la déclaration ci-dessus.

SHOW CREATE TABLE SORTIE:

mysql> SHOW CREATE TABLE carmake; 
+---------+---------------------------------------------------------------------+ 
| Table | Create Table 
+---------+---------------------------------------------------------------------+ 
| carmake | CREATE TABLE `carmake` (
`carmake_id` tinyint(4) NOT NULL AUTO_INCREMENT, 
`name` tinytext, 
`country` enum('Japan','USA','England','Australia','Germany','France','Italy','Spain','Czech Republic','China','South Korea','India') DEFAULT NULL, 
PRIMARY KEY (`carmake_id`), 
KEY `name` (`name`(3)) 
) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=latin1 | 
+---------+---------------------------------------------------------------------+ 
1 row in set (0.00 sec) 

SELECT pays DISTINCT carmake SORTIE:

+----------------+ 
| country  | 
+----------------+ 
| Italy   | 
| Germany  | 
| England  | 
| USA   | 
| France   | 
| South Korea | 
| NULL   | 
| Australia  | 
| Spain   | 
| Czech Republic | 
+----------------+ 

Répondre

63

Le discussion j'ai eu avec Asaph peut être difficile de suivre comme nous sommes retournés en arrière un peu.

Je pensais que je pourrais clarifier le résultat de notre discours pour d'autres qui pourraient faire face à des situations similaires à l'avenir bénéficier de:

ENUM colonnes de -type sont des bêtes très difficiles à manipuler. Je voulais ajouter deux pays (Malaisie & Suède) à l'ensemble des pays existants dans mon ENUM.

Il semble que MySQL 5.1 (qui est ce que je suis en cours d'exécution) ne peut mettre à jour le ENUM en redéfinissant l'ensemble existant en plus de ce que je veux:

Cela ne fonctionne pas:

ALTER TABLE carmake CHANGE country country ENUM('Sweden','Malaysia') DEFAULT NULL; 

La raison en était que l'instruction MySQL remplaçait l'ENUM existant par une autre contenant les entrées 'Malaysia' et 'Sweden' seulement. MySQL a généré une erreur car la table carmake avait déjà des valeurs comme 'England' et 'USA' qui ne faisaient pas partie de la nouvelle définition de ENUM.

Étonnamment, ce qui suit ne fonctionne pas non plus:

ALTER TABLE carmake CHANGE country country ENUM('Australia','England','USA'...'Sweden','Malaysia') DEFAULT NULL; 

Il se avère que même l'ordre des éléments des besoins existants ENUM à conserver tout en y ajoutant de nouveaux membres à lui. Donc, si mon ENUM existant ressemble à ENUM('England','USA'), mon nouveau ENUM doit être défini comme ENUM('England','USA','Sweden','Malaysia') et non ENUM('USA','England','Sweden','Malaysia'). Ce problème ne se manifeste que lorsqu'il existe des enregistrements dans la table existante qui utilisent les valeurs 'USA' ou 'England'.

BOTTOM LINE:

Utilisez uniquement ENUM s lorsque vous ne vous attendez pas votre ensemble de membres pour changer une fois défini. Sinon, les tables de recherche sont beaucoup plus faciles à mettre à jour et à modifier.

+0

Je me risquerais à une ligne de fond plus forte ... "n'utiliser ENUMs que lorsque vous êtes 100% morts certain que les valeurs ne changeront jamais". Si une table devient grande, ce sera pénible si vous devez changer ces valeurs. – DougW

+5

Je ne suis pas sûr d'être d'accord avec ce résultat. Croyez-moi, je n'aime pas du tout ENUM mais je ne vois pas le danger d'ajouter à l'ENUM possible. ENUM est, à son noyau, un mappage de 0 -> Option 1, 1-> Option 2, etc. Ajouter à cela ne devrait pas causer de problème. – JoshStrange

+2

@JoshStrange Ce n'est pas tellement un danger, cela peut être un gros inconvénient lorsque l'ordre de votre ENUM est important (par exemple, lorsqu'il est utilisé pour la commande). – 1in9ui5t

84

Votre code fonctionne pour moi. Voici mon cas de test:

mysql> CREATE TABLE carmake (country ENUM('Canada', 'United States')); 
Query OK, 0 rows affected (0.00 sec) 

mysql> SHOW CREATE TABLE carmake; 
+---------+-------------------------------------------------------------------------------------------------------------------------+ 
| Table | Create Table                           | 
+---------+-------------------------------------------------------------------------------------------------------------------------+ 
| carmake | CREATE TABLE `carmake` (
    `country` enum('Canada','United States') default NULL 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 | 
+---------+-------------------------------------------------------------------------------------------------------------------------+ 
1 row in set (0.00 sec) 

mysql> ALTER TABLE carmake CHANGE country country ENUM('Sweden','Malaysia'); 
Query OK, 0 rows affected (0.53 sec) 
Records: 0 Duplicates: 0 Warnings: 0 

mysql> SHOW CREATE TABLE carmake; 
+---------+--------------------------------------------------------------------------------------------------------------------+ 
| Table | Create Table                          | 
+---------+--------------------------------------------------------------------------------------------------------------------+ 
| carmake | CREATE TABLE `carmake` (
    `country` enum('Sweden','Malaysia') default NULL 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 | 
+---------+--------------------------------------------------------------------------------------------------------------------+ 
1 row in set (0.00 sec) 

Quelle erreur voyez-vous?

FWIW ce travaillerions aussi:

ALTER TABLE carmake MODIFY COLUMN country ENUM('Sweden','Malaysia');

je recommande en fait une table de pays plutôt que la colonne de ENUM. Il se peut que vous ayez des centaines de pays qui vous donneront une idée assez vaste et embarrassante.

EDIT: Maintenant que je peux voir votre message d'erreur:

ERROR 1265 (01000): Data truncated for column 'country' at row 1.

Je suppose que vous avez des valeurs dans votre colonne de pays qui ne figurent pas dans votre ENUM. Quelle est la sortie de la commande suivante?

SELECT DISTINCT country FROM carmake;

AUTRE EDIT: Quelle est la sortie de la commande suivante?

SHOW VARIABLES LIKE 'sql_mode';

Est-il STRICT_TRANS_TABLES ou STRICT_ALL_TABLES? Cela pourrait conduire à une erreur, plutôt que l'avertissement habituel que MySQL vous donnerait dans cette situation.

ENCORE UN AUTRE EDIT: Ok, je vois maintenant que vous avez certainement des valeurs dans le tableau qui ne sont pas dans le nouveau ENUM. La nouvelle définition ENUM n'autorise que 'Sweden' et 'Malaysia'. La table a 'USA', 'India' et plusieurs autres.

EDIT DERNIER (PEUT-ÊTRE): Je pense que vous essayez de le faire:

ALTER TABLE carmake CHANGE country country ENUM('Italy', 'Germany', 'England', 'USA', 'France', 'South Korea', 'Australia', 'Spain', 'Czech Republic', 'Sweden', 'Malaysia') DEFAULT NULL;
+0

Il y a plus d'une colonne dans ma table 'carmake'. Cela pourrait-il avoir quelque chose à voir avec ça? – Zaid

+0

Peu probable, mais postez la sortie de cette commande "SHOW CREATE TABLE carmake" et je vais le regarder. – Asaph

+0

@Zaid Je vois que vous avez ajouté le message d'erreur "L'erreur que je reçois est: ERREUR 1265 (01000): Données tronquées pour la colonne" pays "à la ligne 1.". Je pense que le problème est que vous avez déjà des valeurs dans la colonne country qui ne sont pas listées dans l'énumération. – Asaph

-7

C'est possible si vous y croyez. Hehe. essayez ce code.

public function add_new_enum($new_value) 
    { 
    $table="product"; 
    $column="category"; 
     $row = $this->db->query("SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS 
     WHERE TABLE_NAME = ? AND COLUMN_NAME = ?", array($table, $column))->row_array(); 

    $old_category = array(); 
    $new_category=""; 
    foreach (explode(',', str_replace("'", '', substr($row['COLUMN_TYPE'], 5, (strlen($row['COLUMN_TYPE']) - 6)))) as $val) 
    { 
     //getting the old category first 

     $old_category[$val] = $val; 
     $new_category.="'".$old_category[$val]."'".","; 
    } 

    //after the end of foreach, add the $new_value to $new_category 

     $new_category.="'".$new_value."'"; 

    //Then alter the table column with the new enum 

    $this->db->query("ALTER TABLE product CHANGE category category ENUM($new_category)"); 
    } 

Before adding new value

After adding new value

+6

Je ne vois pas comment cela apporte quelque chose de nouveau à la table. La question est purement du point de vue de MySQL. Votre réponse incorpore du PHP aléatoire qui est complètement hors de propos et vous ne tentez pas d'expliquer quoi que ce soit.Une ressource inutile d'information – Jonathan

31
ALTER TABLE 
    `table_name` 
MODIFY COLUMN 
    `column_name2` enum(
     'existing_value1', 
     'existing_value2', 
     'new_value1', 
     'new_value2' 
    ) 
NOT NULL AFTER `column_name1`; 
+2

une réponse claire et rapide utilisable merci. – Andrew

0

Pour votre information: Un outil de simulation utile - phpMyAdmin avec Wampserver 3.0.6 - Aperçu SQL: J'utilise 'Aperçu SQL' pour voir le code SQL qui serait être généré avant de sauvegarder la colonne avec le changement à ENUM. Preview SQL

Ci-dessus vous voyez que je suis entré dans « Ford », « Toyota » dans le ENUM mais je reçois la syntaxe ENUM (0) qui génère une erreur de syntaxe Query error 1064#

je puis copier et coller et modifier le SQL et exécutez-le via SQL avec un résultat positif.

SQL changed

C'est un quickfix que je l'utilise souvent et peuvent également être utilisés sur des valeurs ENUM existantes qui doivent être modifiés. Pensé que cela pourrait être utile.

0

Dans la version du serveur MYSQL: 5.0.27 J'ai essayé et cela a fonctionné très bien pour moi de vérifier dans votre version

ALTER TABLE carmake 
    MODIFY `country` ENUM('Japan', 'USA', 'England', 'Australia', 'Germany', 'France', 'Italy', 'Spain', 'Czech Republic', 'China', 'South Korea', 'India', 'Sweden', 'Malaysia'); 
Questions connexes