2009-10-01 2 views
104

Справочное руководство по MySQL не дает четкого примера о том, как это сделать.Как добавить больше членов в столбец типа ENUM в MySQL?

У меня есть столбец названия ENUM, в котором мне нужно добавить больше стран. Каков правильный синтаксис MySQL для достижения этого?

Вот моя попытка:

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

Ошибки я получаю: ERROR 1265 (01000): Data truncated for column 'country' at row 1.

Колонка country является столбец ENUM-типа в вышеприведенном заявлении.

SHOW CREATE TABLE ВЫВОД:

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 DISTINCT FROM страна carmake ВЫХОД:

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

ответ

63

discussion я имел с Асафа может быть нечетким, чтобы следовать, как мы пошли вперед и назад совсем немного.

Я думал, что я мог бы прояснить развязку нашего дискурса для других людей, которые могут столкнуться с подобными ситуациями в будущем воспользоваться:

ENUM -типа колонны очень сложные животные, чтобы манипулировать. Я хотел добавить две страны (Малайзия & Швеция) в существующий набор стран в моем ENUM.

кажется, что MySQL 5.1 (который является то, что я бегу) может обновить только ENUM путем пересмотра существующего набора в дополнение к тому, что я хочу:

Это не сработало:

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

Причина заключалась в том, что оператор MySQL заменял существующий ENUM на другой, содержащий только записи 'Malaysia' и 'Sweden'. MySQL запустил ошибку, потому что таблица carmake уже имела такие значения, как 'England' и 'USA', которые не были частью нового определения ENUM.

Удивительно, но следующий не сработало:

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

Оказывается, что даже порядок элементов существующих ENUM должна быть сохранена при добавлении новых членов к нему. Так что если мой существующий ENUM выглядит примерно как ENUM('England','USA'), то мой новый ENUM должен быть определен как ENUM('England','USA','Sweden','Malaysia'), а не ENUM('USA','England','Sweden','Malaysia'). Эта проблема становится очевидной только при наличии записей в существующей таблице, которые используют значения 'USA' или 'England'.

ИТОГ:

использовать только ENUM сек, когда вы не ожидаете, что ваш набор элементов, чтобы изменить однажды определил. В противном случае таблицы поиска намного проще обновлять и изменять.

+0

Я бы рискнул получить более сильный результат ... «используйте только ENUM, когда вы на 100% уверены, что уверены, что значения никогда не изменятся». Если таблица станет большой, будет боль, если вам когда-либо придется изменить эти значения. – DougW

+5

Я не уверен, что согласен с этим. Поверьте мне, мне совсем не нравится ENUM, но я не вижу опасности в добавлении к возможному ENUM. ENUM - это, по сути, сопоставление 0 -> Вариант 1, 1-> Вариант 2 и т. Д. Добавление к этому не должно вызывать проблемы. – JoshStrange

+2

@JoshStrange Это не так опасно, это может быть огромным неудобством, когда порядок вашего ENUM важен (например, при заказе). – 1in9ui5t

84

Ваш код работает для меня. Вот мой тестовый пример:

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) 

Какая ошибка вы видите?

FWIW это будет работать:

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

Я бы на самом деле рекомендую таблицу стран, а не колонки перечислений. У вас могут быть сотни стран, которые сделают для довольно большого и неудобного перечисления.

EDIT: Теперь, когда я могу видеть ваше сообщение об ошибке:

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

Я подозреваю, что у вас есть какое-то значение в столбце страны, которые не появляются в вашем ENUM. Каков результат следующей команды?

SELECT DISTINCT country FROM carmake;

ДРУГОЕ ИЗОБРАЖЕНИЕ: Каков результат следующей команды?

SHOW VARIABLES LIKE 'sql_mode';

ли STRICT_TRANS_TABLES или STRICT_ALL_TABLES? Это может привести к ошибке, а не к обычному предупреждению, которое MySQL предоставит вам в этой ситуации.

YET ANOTHER EDIT: Хорошо, теперь я вижу, что у вас определенно есть значения в таблице, которые не находятся в новом ENUM. Новое определение ENUM допускает только 'Sweden' и 'Malaysia'. Таблица имеет 'USA', 'India' и некоторые другие.

ПОСЛЕДНИЙ EDIT (ВОЗМОЖНО): Я думаю, что вы пытаетесь сделать это:

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

Там больше, чем один столбец в моей 'carmake' таблицы. Может ли это иметь к этому какое-нибудь отношение? – Zaid

+0

Вряд ли, но опубликуйте вывод этой команды «SHOW CREATE TABLE carmake», и я посмотрю на это. – Asaph

+0

@ Zaid Я вижу, что вы добавили сообщение об ошибке «Ошибка, которую я получаю: ERROR 1265 (01000): данные усекаются для столбца« страна »в строке 1.». Я думаю, проблема заключается в том, что у вас есть значения уже в столбце страны, которые не перечислены в перечислении. – Asaph

-7

Это возможно, если вы считаете. Хехе. попробуйте этот код.

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

Я не вижу, как это приносит ничего нового в таблицу. Вопрос идет исключительно с точки зрения MySQL. Ваш ответ включает случайный PHP, который абсолютно не имеет значения, и вы не пытаетесь объяснить его.Бесполезный ресурс информации – 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

ясный и быстрый полезный ответ спасибо. – Andrew

0

FYI: полезный инструмент моделирования - PhpMyAdmin с WampServer 3.0.6 - Просмотр SQL: Я использую 'Preview SQL', чтобы увидеть код SQL, который будет создаваться до сохранения столбца с изменением на ENUM. Preview SQL

Выше вы видите, что я вступил в «Форд», «Тойота» в ENUM, но я получаю синтаксис ENUM (0), который генерирует синтаксическую ошибку Query error 1064#

затем скопировать и вставить и изменить SQL и запустить его через SQL с положительным результатом.

SQL changed

Это QuickFix, что я часто использую, а также могут быть использованы на существующие значения ENUM, которые должны быть изменены. Думал, что это может быть полезно.

0

В версии сервера MySQL: 5.0.27 я попытался это и она работала хорошо для меня проверить в вашей версии

ALTER TABLE carmake 
    MODIFY `country` ENUM('Japan', 'USA', 'England', 'Australia', 'Germany', 'France', 'Italy', 'Spain', 'Czech Republic', 'China', 'South Korea', 'India', 'Sweden', 'Malaysia'); 
Смежные вопросы