我有两个数据库,一个表,一个utf8
表,我想更改列的编码,我使用了两个场景,但一个问题发生在我身上。起初桌子是这样的:
CREATE TABLE `spool` (
`username` varchar(250) NOT NULL,
`xml` text NOT NULL,
`seq` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY `seq` (`seq`),
KEY `i_despool` (`username`) USING BTREE,
KEY `i_spool_created_at` (`created_at`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
第一种情况
在第一个中,我使用以下命令更改行编码:
ALTER TABLE spool MODIFY xml TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
然后我show create table spool;
像这样使用:
CREATE TABLE `spool` (
`username` varchar(250) NOT NULL,
`xml` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`seq` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY `seq` (`seq`),
KEY `i_despool` (`username`) USING BTREE,
KEY `i_spool_created_at` (`created_at`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
第二种情况
在第二个表中,我首先更改了表编码,然后更改了xml
列编码,如下所示:
ALTER TABLE spool
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
然后我更改了列编码,如下所示:
ALTER TABLE spool MODIFY xml TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
然后我们可以看到这样的表格:
CREATE TABLE `spool` (
`username` varchar(250) COLLATE utf8mb4_unicode_ci NOT NULL,
`xml` text COLLATE utf8mb4_unicode_ci NOT NULL,
`seq` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY `seq` (`seq`),
KEY `i_despool` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=30849368 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
正如您在“`xml`文本”前面的第二种情况中看到的那样,我们看不到CHARACTER SET utf8mb4
,我认为这对我来说会导致错误,因为当 Ejabberd 想要在第二个中插入查询时,我看到以下错误但在另一个表我没有这个错误:
HY000Incorrect string value: '\\xF0\\x9F\\x98\\x8F\\xF0\\x9F...' for column 'xml' at row 1"
** Stacktrace: [{ejabberd_odbc,sql_query_t,1,[{file,"src/ejabberd_odbc.erl"},{line,173}]},{lists,foreach,2,[{file,"lists.erl"},{line,1336}]},{ejabberd_odbc,outer_transaction,3,[{file,"src/ejabberd_odbc.erl"},{line,443}]},{ejabberd_odbc,run_sql_cmd,4,[{file,"src/ejabberd_odbc.erl"},{line,380}]},{p1_fsm,handle_msg,10,[{file,"src/p1_fsm.erl"},{line,582}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,237}]}]
在第一种情况下,我们看不到此错误,但在第二种情况下存在错误。如何解决这个问题呢?
有趣的问题。看起来在第二种情况下,您首先转换 table 的默认字符集:
那么你尝试对你的列进行
MODIFY
字符集。xml
但是数据库可能认为该列已经在所需的字符集中(请记住您已经更改了默认字符集)尝试使用这样的查询(参见 mysql 手册的同一页):
您是说(在这两种情况下)执行了一个
INSERT
xml 包含?
。它在第一种情况下有效,但在第二种情况下出错?描述客户端——它的连接参数等。
一开始一切都很顺利。
SET NAMES utf8mb4
我怀疑它在连接字符串中是正确的说法或等价物。但第二个案例似乎是用
utf8
.或者你是说那
?
在表格中,并且ALTER
引发了错误消息?答案:
伙计们回答了这个问题,但我也在这里补充几点:
正如大家所说,当我们设置表的默认字符集时,如下所示:
在我们
xml
像这样设置列字符集之后:MySQL 认为
xml
列字符集已设置,因此不会发生任何更改,字符集将显示如下:这会导致插入表时出现一些错误,因为
xml
尚未设置真正的字符集,我认为这可能是一个错误。我回滚了spool
表默认字符集。这导致该
xml
字符集现在是正确的:而且我也没有从 Ejabberd 获得数据库错误。