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!
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.
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. :)
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` ;
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.
J'ai fini par faire ce qui suit:
mysqldump db_name > db_name.sql
sed -i -e 's/old_charset/new_charset/g' db_name.sql
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.