Tenho dois banco de dados com uma tabela com utf8
tabela, queria mudar a codificação de uma coluna, usei dois cenários mas aconteceu um problema comigo. a princípio a tabela era assim:
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
Primeiro cenário
no primeiro eu mudo a codificação da linha com o comando abaixo:
ALTER TABLE spool MODIFY xml TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
e então eu uso show create table spool;
assim:
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
segundo cenário
Na segunda tabela, alterei primeiro a codificação da tabela e depois alterei a xml
codificação da coluna assim:
ALTER TABLE spool
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
e então mudei a codificação da coluna como abaixo:
ALTER TABLE spool MODIFY xml TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
e então podemos ver a tabela como esta:
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
como você pode ver no segundo cenário na frente do "texto `xml`" não vemos o CHARACTER SET utf8mb4
e acho que causa erro para mim porque quando o Ejabberd deseja inserir uma consulta no segundo, vejo o erro abaixo, mas em a outra tabela não tenho esse erro:
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}]}]
no primeiro cenário não vemos este erro mas no segundo o erro existe. Como resolver este problema?
Pergunta interessante. Parece que no segundo cenário você primeiro converte charset padrão para tabela :
Então você tenta o
MODIFY
charset da suaxml
coluna. Mas o banco de dados pode pensar que esta coluna já está no conjunto de caracteres desejado (lembre-se de que você já alterou o conjunto de caracteres padrão)Tente usar uma consulta como esta ( veja a mesma página do manual do mysql ):
Você está dizendo (em ambos os casos) que um
INSERT
contendo xml?
foi executado. E que funcionou no primeiro caso, mas deu erro no segundo caso?Descreva o cliente -- seus parâmetros de conexão, etc.
No primeiro tudo correu bem. Eu suspeito que estava dizendo corretamente
SET NAMES utf8mb4
ou o equivalente na string de conexão.Mas o segundo caso parecia ter sido feito com
utf8
.Ou você está dizendo que
?
estava na tabela eALTER
gerou a mensagem de erro?Resposta :
caras responderam a esta questão, mas eu adiciono alguns pontos aqui também:
como os caras disseram, quando definimos o conjunto de caracteres padrão da tabela como abaixo:
e depois de definirmos o conjunto de
xml
caracteres da coluna assim:O MySQL pensa que o
xml
conjunto de caracteres da coluna foi definido para que nenhuma alteração ocorra e o conjunto de caracteres será mostrado como:isso causa alguns erros na inserção na tabela porque realmente o
xml
conjunto de caracteres não foi definido e acho que isso pode ser um bug. Eu reverti ospool
conjunto de caracteres padrão da tabela.Isso fez com que o
xml
conjunto de caracteres agora esteja correto:e também não recebo o erro do banco de dados do Ejabberd.