我正在协助从MySQL 4到MySQL 5.5的数据库升级。我的客户端的应用程序服务器也已从JDK 5升级到JDK 7.但是,在执行数据库操作时,应用程序运行会引发许多异常。
我发现升级后的数据库在表排序规则和/或表列排序规则中使用了Latin1泛型,Latin1瑞典语和UTF8泛型的混合,因此大多数JOIN查询都失败了。
有数百个表和数千个表字段,手动转换所有表格将非常困难。
是否有更方便的方法将所有数据表和所有列转换为相同的排序规则?
谢谢。
编辑:显示JOIN查询失败的SQLException消息示例:
“非法混合排序(latin1_general_ci,IMPLICIT)和(utf8_general_ci,COERCIBLE)进行操作'='”
答案 0 :(得分:7)
混合使用字符集不应导致查询失败,因为MySQL应根据需要在字符集之间进行转换。
但是,如ALTER TABLE
Syntax所述:
要将表默认字符集和所有字符列(
CHAR
,VARCHAR
,TEXT
)更改为新字符集,请使用如下语句:ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;
对于数据类型为
VARCHAR
或其中一种TEXT
类型的列,CONVERT TO CHARACTER SET
会根据需要更改数据类型,以确保新列的长度足以支持存储与原始列一样多的字符。例如,TEXT
列有两个长度字节,用于存储列中值的字节长度,最大值为65,535。对于latin1
TEXT
列,每个字符都需要一个字节,因此该列最多可以存储65,535个字符。如果列转换为utf8
,则每个字符最多可能需要三个字节,最大可能长度为3×65,535 = 196,605字节。该长度不适合TEXT
列的长度字节,因此MySQL将数据类型转换为MEDIUMTEXT
,这是长度字节可以记录值196,605的最小字符串类型。同样,VARCHAR
列可能会转换为MEDIUMTEXT
。为避免更改上述类型的数据类型,请勿使用
CONVERT TO CHARACTER SET
。而是使用MODIFY
更改单个列。例如:ALTER TABLE t MODIFY latin1_text_col TEXT CHARACTER SET utf8; ALTER TABLE t MODIFY latin1_varchar_col VARCHAR(M) CHARACTER SET utf8;
如果您指定
CONVERT TO CHARACTER SET binary
,则CHAR
,VARCHAR
和TEXT
列会转换为相应的二进制字符串类型(BINARY
,{{3 },VARBINARY
)。这意味着列不再具有字符集,后续CONVERT TO
操作将不适用于它们。如果
charset_name
为DEFAULT
,则使用数据库字符集。警告
CONVERT TO
操作会在字符集之间转换列值。如果您在一个字符集中有一列(如latin1
),那么不你想要的是什么,但存储的值实际上使用了一些其他不兼容的字符集(如utf8
) 。在这种情况下,您必须为每个此类列执行以下操作:ALTER TABLE t1 CHANGE c1 c1 BLOB; ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;