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)
从汽车制造商输出中选择不同的国家:
+----------------+
| country |
+----------------+
| Italy |
| Germany |
| England |
| USA |
| France |
| South Korea |
| NULL |
| Australia |
| Spain |
| Czech Republic |
+----------------+
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');
我实际上会推荐一个国家表而不是枚举列。您可能有数百个国家/地区,这将构成一个相当大且尴尬的枚举。
编辑:现在我可以看到您的错误消息:
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;
carmake
表中有不止一列。这和它有什么关系吗?
重要提示:这是一个遗留答案
我与 Asaph 的discussion可能不太清楚,因为我们来回走了很多次。
我想我可能会澄清我们演讲的结果,以便将来可能面临类似情况的其他人受益:
ENUM
类型的列是非常难以操作的野兽。我想在我的 ENUM 中的现有国家集中添加两个国家(马来西亚和瑞典)。
似乎 MySQL 5.1(这是我正在运行的)只能通过重新定义现有集合来更新 ENUM,除了我想要的:
这不起作用:
ALTER TABLE carmake CHANGE country country ENUM('Sweden','Malaysia') DEFAULT NULL;
原因是 MySQL 语句将现有 ENUM 替换为仅包含条目 'Malaysia'
和 'Sweden'
的另一个 ENUM。 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
。否则,查找表更容易更新和修改。
在 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');
这是另一种方式...
它将“others”添加到表“firmas”的“rtipo”列的枚举定义中。
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;
仅供参考:一个有用的模拟工具 - 带有 Wampserver 3.0.6 的 phpMyAdmin - 预览 SQL:我使用“预览 SQL”来查看在保存更改为 ENUM 的列之前将生成的 SQL 代码。 Preview SQL
上面你看到我在 ENUM 中输入了 'Ford','Toyota' 但我得到的语法 ENUM(0) 正在生成语法错误 Query error 1064#
然后我复制并粘贴并更改 SQL 并通过 SQL 运行它,结果是肯定的。
这是我经常使用的快速修复,也可以用于需要更改的现有 ENUM 值。认为这可能有用。
mysql data truncated for column 'status' at row 1 enum
如果记录中存在旧值并且更改的 ENUM 不包含它,则可能在添加新枚举值时导致上述错误
如果你相信,这是可能的。呵呵。试试这个代码。
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)");
}
inplace
:mariadb.com/kb/en/library/…