web-dev-qa-db-fra.com

Alter Charset et collation dans toutes les colonnes de toutes les tables de MySQL

Je dois exécuter ces déclarations dans toutes les tables de 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 à l'intérieur de MySQL? Je préférerais éviter MySqldump

Mise à jour: Richard Bronosky m'a montré la voie :-)

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

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

Query fou de 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 base de données. Il faisait 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 par table. Et une seule requête par table était nécessaire (distincte à la rescousse). Obtenir la sortie sur un fichier était de savoir comment 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 questions:

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

Merci Richard. Tu es l'homme!

20
The Disintegrator

Tout d'abord, ne prenez pas simplement 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, supprimez les clauses de limite et enregistrez la sortie sur un script SQL ou, obtenez-vous de la fantaisie et de piloter la sortie directement sur 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 SQL valide pour générer SQL valide, il change tout le jeu. Vous serez émerveillé par le nombre d'utilisations que vous trouvez pour cela.

16
Bruno Bronosky

En fait, vous pouvez utiliser Convertir sur une table pour convertir toutes les colonnes de cette table en caractères et la collation.

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 de plus logique pour moi de sélectionner la base de données réelle que vous souhaitez faire cela. Donc ça:

... WHERE TABLE_SCHEMA = 'databasename';

plutôt que cela:

... WHERE TABLE_SCHEMA != 'information_schema';

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

6
user51876

Pour changer de 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` ;
1
rbh

Vous pouvez utiliser le information_schema Base 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 le changement avec un script SQL, la procédure de stockage ou avec votre langue de développement préférée.

0
lg.

J'ai fini par faire ce qui suit:

  • dublisez la base de données dans un fichier SQL, en utilisant mysqldump db_name > db_name.sql
  • remplacez le charert dans le fichier SQL en utilisant AWK sed -i -e 's/old_charset/new_charset/g' db_name.sql
  • importer ce nouveau fichier de base de données mysql < db_name

Je n'utiliserais pas cela dans la production, mais j'en avais besoin dans un environnement de développement local.

Alternativivement, j'aurais pu jeter la structure et les données SQL séparément, puis je suis allé dans le fichier SQL pour modifier les caractères.

Gardez à l'esprit que si vous convertissez entre des caractères incompatibles, cela pourrait gâcher vos données.

0
Nebojsac