¿Cómo puedo añadir más miembros a mi columna tipo enumeración en MySQL?


El manual de referencia de MySQL no proporciona un ejemplo claro sobre cómo hacer esto.

Tengo una columna tipo enumeración de nombres de países a la que necesito agregar más países. ¿Cuál es la sintaxis MySQL correcta para lograr esto?

Aquí está mi intento:

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

El error que obtengo es: ERROR 1265 (01000): Data truncated for column 'country' at row 1.

La columna country es la columna tipo enumeración en la instrucción above.

MOSTRAR CREAR TABLA SALIDA:

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)

SELECCIONE país DISTINTO DE carmake SALIDA:

+----------------+
| country        |
+----------------+
| Italy          |
| Germany        |
| England        |
| USA            |
| France         |
| South Korea    |
| NULL           |
| Australia      |
| Spain          |
| Czech Republic |
+----------------+
Author: Zaid, 2009-10-01

7 answers

ALTER TABLE
    `table_name`
MODIFY COLUMN
    `column_name2` enum(
        'existing_value1',
        'existing_value2',
        'new_value1',
        'new_value2'
    )
NOT NULL AFTER `column_name1`;
 65
Author: Pradip Chongbang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-25 21:21:13

Tu código funciona para mí. Aquí está mi caso de prueba:

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)

¿Qué error estás viendo?

FWIW esto también funcionaría:

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

En realidad recomendaría una tabla de países en lugar de una columna de enumeración. Usted puede tener cientos de países que harían para un enum bastante grande y torpe.

EDITAR: Ahora que puedo ver su mensaje de error:

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

Sospecho que tiene algunos valores en su columna de país que no aparecen en su ENUM. ¿Qué es el salida del siguiente comando?

SELECT DISTINCT country FROM carmake;

OTRA EDICIÓN: ¿Cuál es la salida del siguiente comando?

SHOW VARIABLES LIKE 'sql_mode';

Es STRICT_TRANS_TABLES o STRICT_ALL_TABLES? Eso podría llevar a un error, en lugar de la advertencia habitual que MySQL le daría en esta situación.

OTRA EDICIÓN: Ok, ahora veo que definitivamente tiene valores en la tabla que no están en el nuevo ENUM. La nueva definición de ENUM solo permite 'Sweden' y 'Malaysia'. La mesa tiene 'USA', 'India' y varios otros.

ÚLTIMO EDITAR (TAL VEZ): Creo que estás tratando de hacer esto:

ALTER TABLE carmake CHANGE country country ENUM('Italy', 'Germany', 'England', 'USA', 'France', 'South Korea', 'Australia', 'Spain', 'Czech Republic', 'Sweden', 'Malaysia') DEFAULT NULL;
 92
Author: Asaph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-21 16:00:34

La discusión que tuve con Asaph puede ser poco clara para seguir a medida que fuimos de ida y vuelta un poco.

Pensé que podría aclarar el resultado de nuestro discurso para que otros que podrían enfrentar situaciones similares en el futuro se beneficien de:

ENUM-las columnas tipo son bestias muy difíciles de manipular. Quería añadir dos países (Malasia y Suecia) al conjunto existente de países en mi ENUMERACIÓN.

Parece que MySQL 5.1 (que es lo que estoy ejecutando) solo se puede actualizar la ENUMERACIÓN redefiniendo el conjunto existente además de lo que quiero:

Esto no funcionó:

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

La razón fue que la instrucción MySQL estaba reemplazando la ENUMERACIÓN existente con otra que contenía las entradas 'Malaysia' y 'Sweden' solamente. MySQL lanzó un error porque la tabla carmake ya tenía valores como 'England' y 'USA' que no formaban parte de la nueva definición de ENUM.

Sorprendentemente, lo siguiente tampoco funcionó:

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

Gira que incluso el orden de los elementos del ENUM existente necesita ser preservado mientras se le agregan nuevos miembros. Así que si mi ENUM existente se parece a ENUM('England','USA'), entonces mi nuevo ENUM tiene que ser definido como ENUM('England','USA','Sweden','Malaysia') y no ENUM('USA','England','Sweden','Malaysia'). Este problema solo se manifiesta cuando hay registros en la tabla existente que usan valores 'USA' o 'England'.

EN POCAS PALABRAS:

Solo use ENUM s cuando no espere que su conjunto de miembros cambie una vez definido. De lo contrario, buscar tablas son mucho más fáciles de actualizar y modificar.

 68
Author: Zaid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:28

Para su información: Una herramienta de simulación útil - phpMyAdmin con Wampserver 3.0.6 - Preview SQL: Uso 'Preview SQL' para ver el código SQL que se generaría antes de guardar la columna con el cambio a ENUM. Vista previa de SQL

Arriba ves que he ingresado 'Ford', 'Toyota' en la enumeración pero estoy obteniendo syntax ENUM (0) que está generando error de sintaxis Error de consulta 1064#

Luego copio y pego y altero el SQL y lo corro a través de SQL con un positivo resultado.

SQL changed

Este es un quickfix que uso a menudo y también se puede usar en valores de ENUMERACIÓN existentes que necesitan ser alterados. Pensé que esto podría ser útil.

 0
Author: Addi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-11 12:09:34

En la versión del servidor MYSQL: 5.0.27 probé esto y funcionó bien para mí comprobar en su versión

ALTER TABLE carmake
     MODIFY `country` ENUM('Japan', 'USA', 'England', 'Australia', 'Germany', 'France', 'Italy', 'Spain', 'Czech Republic', 'China', 'South Korea', 'India', 'Sweden', 'Malaysia');
 0
Author: Abhishek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-25 21:20:30

Aquí hay otra manera...

Añade "otros" a la definición de enumeración de la columna "rtipo" de la tabla "firmas".

set @new_enum = 'others';
set @table_name = 'firmas';
set @column_name = 'rtipo';
select column_type into @tmp from information_schema.columns 
  where table_name = @table_name and column_name=@column_name;
set @tmp = insert(@tmp, instr(@tmp,')'), 0, concat(',\'', @new_enum, '\'') );
set @tmp = concat('alter table ', @table_name, ' modify ', @column_name, ' ', @tmp);
prepare stmt from @tmp;
execute stmt;
deallocate prepare stmt;
 0
Author: Antonio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-06 15:28:25

Es posible si crees. Jeje. prueba este código.

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)");
  }

Antes de añadir un nuevo valor

Después de añadir un nuevo valor

 -8
Author: Alj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-07 20:30:01