Как добавить больше членов в мой столбец типа перечисления в MySQL?


справочное руководство MySQL не дает четкого примера о том, как это сделать.

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

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

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

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

The country столбец-это столбец типа перечисления в приведенном выше операторе.

ПОКАЗАТЬ СОЗДАТЬ ТАБЛИЦУ Вывод:

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)

выберите отдельную страну от carmake выход:

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

7 ответов:

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

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

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 даст вам в этой ситуации.

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

последнее редактирование (возможно): я думаю, что вы пытаетесь сделать это:

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

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

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

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

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

это не работает:

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

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

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

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' ценности.

ИТОГ:

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

FYI: полезный инструмент моделирования-phpMyAdmin с Wampserver 3.0.6-предварительный просмотр SQL: я использую "предварительный просмотр SQL", чтобы увидеть код SQL, который будет сгенерирован перед сохранением столбца с изменением на перечисление. предварительный просмотр SQL

выше вы видите, что я ввел "Ford", "Toyota" в перечисление, но я получаю синтаксис ENUM(0), который генерирует синтаксическую ошибку ошибка запроса 1064#

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

SQL изменен

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

в версии сервера 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');

вот еще один способ...

Он добавляет "другие "к определению перечисления столбца" rtipo "таблицы"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;

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

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

перед добавлением нового значения

после добавления нового значения