Modifier le jeu de caractères et le classement dans toutes les colonnes de toutes les tables dans MySQL

18

J'ai besoin d'exécuter ces instructions dans toutes les tables pour toutes les colonnes.

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

Est-il possible d'automatiser cela de quelque manière que ce soit dans MySQL? Je préfère éviter mysqldump

Mise à jour: Richard Bronosky m'a montré le chemin :-)

La requête que j'avais besoin d'exécuter dans chaque table:

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

Requête folle pour générer toutes les autres requêtes:

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';

Je voulais seulement l'exécuter dans une seule base de données. Cela prenait trop de temps pour exécuter tout en un seul passage. Il s'est avéré qu'il générait une requête par champ et par table. Et une seule requête par table était nécessaire (distincte à la rescousse). Obtenir la sortie sur un fichier est la façon dont je l'ai réalisé.

Comment générer la sortie dans un fichier:

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

Et enfin pour exécuter toutes les requêtes:

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

Merci Richard. Tu es l'homme!

Le désintégrateur
la source

Réponses:

16

Tout d'abord, ne vous fiez pas seulement à ma parole! Testez ma suggestion avec ceci:

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;

Si vous vous sentez bien avec le résultat de cela, supprimez les clauses limites et enregistrez la sortie dans un script SQL ou, fantaisie et dirigez la sortie directement vers mysql similaire à ce que je démontre ici . Cela ressemblerait à ceci:

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

Lorsque vous commencez à penser à utiliser du SQL valide pour générer du SQL valide, cela change tout le jeu. Vous serez étonné du nombre d'utilisations que vous en trouverez.

Bruno Bronosky
la source
Presque là! Mais je n'arrive pas à trouver la bonne syntaxe
The Disintegrator
ok je l'ai. J'ajoute la sintax correcte à la réponse. Votre idée règne
The Disintegrator
4

En fait, vous pouvez utiliser CONVERT TO sur une table pour qu'elle convertisse toutes les colonnes de cette table en charset et en classement.

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';

En outre, il est plus logique pour moi de sélectionner la base de données réelle sur laquelle vous souhaitez effectuer cette opération. Donc ça:

... WHERE TABLE_SCHEMA = 'databasename';

plutôt que ça:

... WHERE TABLE_SCHEMA != 'information_schema';

Mais je suppose que si vous vouliez vraiment le faire sur toutes les tables, vous pourriez utiliser le premier. Cela me semble cependant un peu lourd. :)


la source
1

Pour modifier le classement sur toutes les colonnes que j'ai utilisées

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
la source
0

Vous pouvez utiliser la information_schemabase de données pour trouver la colonne et la table que vous devez modifier. Vous pouvez les trouver avec:

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

Ensuite, vous pouvez automatiser la modification avec un script SQL, une procédure de stockage ou avec votre langage de développement préféré.

lg.
la source