Alterar charset e agrupamento em todas as colunas em todas as tabelas no MySQL

18

Eu preciso executar essas instruções em todas as tabelas para todas as colunas.

alter table table_name charset=utf8;
alter table table_name alter column column_name charset=utf8;

É possível automatizar isso de alguma forma dentro do MySQL? Eu preferiria evitar o mysqldump

Atualização: Richard Bronosky me mostrou o caminho :-)

A consulta que eu precisava executar em todas as tabelas:

alter table DBname.DBfield CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

Consulta maluca para gerar todas as outras consultas:

SELECT distinct CONCAT( 'alter table ', TABLE_SCHEMA, '.', TABLE_NAME, '  CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;' ) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'DBname';

Eu só queria executá-lo em um banco de dados. Estava demorando muito para executar tudo de uma só vez. Descobriu-se que estava gerando uma consulta por campo por tabela. E apenas uma consulta por tabela era necessária (diferente do resgate). Obter a saída em um arquivo foi como eu percebi isso.

Como gerar a saída para um arquivo:

mysql -B -N --user=user --password=secret -e "SELECT distinct CONCAT( 'alter table ', TABLE_SCHEMA, '.', TABLE_NAME, '  CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;' ) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'DBname';" > alter.sql

E, finalmente, para executar todas as consultas:

mysql --user=user --password=secret < alter.sql

Obrigado Richard. Você é o cara!

O Desintegrador
fonte

Respostas:

16

Primeiro de tudo, não basta acreditar na minha palavra! Teste minha sugestão com isso:

select CONCAT('alter table ',TABLE_SCHEMA,'.',TABLE_NAME,' charset=utf8;') from information_schema.TABLES WHERE TABLE_SCHEMA != 'information_schema' limit 10; select CONCAT('alter table ',TABLE_SCHEMA,'.',TABLE_NAME,' alter column ',COLUMN_NAME,' charset=utf8;') from information_schema.COLUMNS WHERE TABLE_SCHEMA != 'information_schema' limit 10;

Se você se sentir bem com o resultado disso, remova as cláusulas limit e salve a saída em um script SQL ou, seja extravagante e canalize a saída diretamente para o mysql, semelhante ao que demonstro aqui . Isso seria assim:

mysql -B -N --host=prod-db1 --user=admin --password=secret -e "select CONCAT('alter table ',TABLE_SCHEMA,'.',TABLE_NAME,' charset=utf8;') from information_schema.TABLES WHERE TABLE_SCHEMA != 'information_schema'; select CONCAT('alter table ',TABLE_SCHEMA,'.',TABLE_NAME,' alter column ',COLUMN_NAME,' charset=utf8;') from information_schema.COLUMNS WHERE TABLE_SCHEMA != 'information_schema';" | mysql --host=prod-db1 --user=admin --password=secret

Quando você começa a pensar em usar SQL válido para gerar SQL válido, ele muda o jogo inteiro. Você ficará surpreso com quantos usos você encontra para isso.

Bruno Bronosky
fonte
Quase lá! Mas não pode obter o direito de sintaxe
O Disintegrator
ok eu entendi. Estou adicionando a sintaxe correta à resposta. Suas regras ideia
o desintegrador
4

Na verdade, você pode usar CONVERT TO em uma tabela para converter todas as colunas nessa tabela para o conjunto de caracteres e agrupamento.

SELECT CONCAT('ALTER TABLE ',TABLE_SCHEMA,'.',TABLE_NAME,' CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;') FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'databasename';

Além disso, faz mais sentido para mim selecionar o banco de dados real no qual você deseja fazer isso. Então, é isso:

... WHERE TABLE_SCHEMA = 'databasename';

em vez disso:

... WHERE TABLE_SCHEMA != 'information_schema';

Mas acho que se você realmente quisesse fazer isso em todas as mesas, poderia usar o primeiro. Parece um pouco pesado para mim. :)


fonte
1

Para alterar o agrupamento em todas as colunas que usei

SELECT CONCAT(  'ALTER TABLE ',  `TABLE_NAME` ,  ' CHANGE `',  `COLUMN_NAME` ,  '` `',`COLUMN_NAME` ,  '` ',  `DATA_TYPE` ,  '(',  `CHARACTER_MAXIMUM_LENGTH` ,  ') CHARACTER SET utf8 COLLATE utf8_swedish_ci ;' ) FROM  `COLUMNS` WHERE  `TABLE_SCHEMA` =  <schema> AND  `COLLATION_NAME` !=  'utf8_swedish_ci' ORDER BY  `TABLE_NAME` ,  `ORDINAL_POSITION` ;
rbh
fonte
0

Você pode usar o information_schemabanco de dados para encontrar a coluna e a tabela que precisa alterar. Você pode encontrá-los com:

SELECT table_name, column_name FROM information_schema.`COLUMNS`
WHERE table_schema='your database' AND collation_name LIKE 'latin%';

Em seguida, você pode automatizar a alteração com um script SQL, procedimento de armazenamento ou com sua linguagem de desenvolvimento preferida.

lg.
fonte