Как добавить больше членов в столбец типа ENUM в MySQL?
Справочное руководство по 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 в приведенном выше описании.
ПОКАЗАТЬ СОЗДАТЬ ТАБЛИЦУ ВЫХОД:
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 OUTPUT:
+----------------+
| country |
+----------------+
| Italy |
| Germany |
| England |
| USA |
| France |
| South Korea |
| NULL |
| Australia |
| Spain |
| Czech Republic |
+----------------+
Ответы
Ответ 1
Обсуждение , которое я имел с Асафом, может быть неясным, потому что мы немного поехали туда и обратно.
Я подумал, что я могу прояснить результат нашего дискурса для других, которые могут столкнуться с подобными ситуациями в будущем, чтобы извлечь выгоду из:
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'
.
BOTTOM LINE:
Используйте только ENUM
, если вы не ожидаете, что ваш набор членов изменится после определения. В противном случае таблицы поиска намного проще обновлять и изменять.
Ответ 2
Ваш код работает для меня. Вот мой тестовый пример:
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');
Я бы рекомендовал таблицу country table вместо столбца enum. У вас могут быть сотни стран, которые сделают для довольно большого и неудобного перечисления.
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 предоставит вам в этой ситуации.
ПОЛУЧИТЕ ДРУГОЙ РЕДАКТ: Хорошо, теперь я вижу, что у вас определенно есть значения в таблице, которые не находятся в новом ENUM
. Новое определение ENUM
допускает только 'Sweden'
и 'Malaysia'
. Таблица имеет 'USA'
, 'India'
и несколько других.
LAST EDIT (MAYBE): Я думаю, вы пытаетесь это сделать:
ALTER TABLE carmake CHANGE country country ENUM('Italy', 'Germany', 'England', 'USA', 'France', 'South Korea', 'Australia', 'Spain', 'Czech Republic', 'Sweden', 'Malaysia') DEFAULT NULL;
Ответ 3
ALTER TABLE table_name
ИЗМЕНИТЬ КОЛОННУЮ column_name2
перечисление ( 'Existing_value1', 'Existing_value2', 'New_value1', 'New_value2' )
NOT NULL AFTER column_name1
;
Ответ 4
Возможно, если верить. Хехе. попробуйте этот код.
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)");
}
Перед добавлением нового значения
После добавления нового значения