## 10.7 列字符集转换

要将二进制或非二进制字符串列转换为使用特定字符集，请使用[`更改表`](alter-table.html).要成功转换，必须满足以下条件之一：

-   如果列具有二进制数据类型 ([`二进制`](binary-varbinary.html),[`变量`](binary-varbinary.html),[`斑点`](blob.html))，它包含的所有值都必须使用单个字符集（您要将列转换为的字符集）进行编码。如果使用二进制列将信息存储在多个字符集中，MySQL 无法知道哪些值使用哪个字符集，无法正确转换数据。

-   如果列具有非二进制数据类型 ([`字符`](char.html),[`VARCHAR`](char.html),[`文本`](blob.html))，其内容应以列字符集编码，而不是其他字符集。如果内容以不同的字符集编码，您可以先将该列转换为使用二进制数据类型，然后再转换为具有所需字符集的非二进制列。

    假设一个表`吨`有一个名为的二进制列`col1`定义为`VARBINARY(50)`.假设列中的信息使用单个字符集进行编码，您可以将其转换为具有该字符集的非二进制列。例如，如果`col1`包含表示字符的二进制数据`希腊语`字符集，可以如下转换：


```
ALTER TABLE t MODIFY col1 VARCHAR(50) CHARACTER SET greek;
```

如果您的原始列的类型为`二进制（50）`，您可以将其转换为`字符(50)`，但结果值用`0x00`最后的字节，这可能是不可取的。要删除这些字节，请使用[`修剪（）`](string-functions.html#function_trim)功能：

```
UPDATE t SET col1 = TRIM(TRAILING 0x00 FROM col1);
```

假设那张桌子`吨`有一个名为的非二进制列`col1`定义为`CHAR(50) 字符集 latin1`但您想将其转换为使用`utf8`这样您就可以存储多种语言的值。下面的语句实现了这一点：

```
ALTER TABLE t MODIFY col1 CHAR(50) CHARACTER SET utf8;
```

如果列包含不在两个字符集中的字符，则转换可能有损。

如果您有 MySQL 4.1 之前的旧表，其中非二进制列包含实际上以不同于服务器默认字符集的字符集编码的值，则会发生一种特殊情况。例如，应用程序可能已存储`sjis`列中的值，即使 MySQL 的默认字符集不同。可以将列转换为使用正确的字符集，但需要额外的步骤。假设服务器的默认字符集是`拉丁语1`和`col1`定义为`字符(50)`但它的内容是`sjis`价值观。第一步是将列转换为二进制数据类型，即去掉已有的字符集信息而不进行任何字符转换：

```
ALTER TABLE t MODIFY col1 BLOB;
```

下一步是将列转换为具有正确字符集的非二进制数据类型：

```
ALTER TABLE t MODIFY col1 CHAR(50) CHARACTER SET sjis;
```

此过程要求该表尚未使用以下语句修改[`插入`](insert.html)要么[`更新`](update.html)升级到 MySQL 4.1 或更高版本后。在这种情况下，MySQL 将使用`拉丁语1`，并且该列将包含`sjis`和`拉丁语1`值，无法正确转换。

如果您在最初创建列时指定了属性，则还应在更改表时指定它们[`更改表`](alter-table.html).例如，如果您指定`非空`和一个明确的`默认`值，您还应该在[`更改表`](alter-table.html)陈述。否则，生成的列定义不包括这些属性。

要转换表中的所有字符列，`ALTER TABLE ... 转换为字符集 *`字符集`*`声明可能有用。看[第 13.1.9 节，“ALTER TABLE 语句”](alter-table.html).
