web-dev-qa-db-ja.com

MySQLのすべてのテーブルのすべての列の文字セットと照合順序を変更する

すべての列のすべてのテーブルでこれらのステートメントを実行する必要があります。

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

MySQL内でこれを何らかの方法で自動化することは可能ですか? mysqldumpは避けたい

更新:リチャードブロノスキーは私に方法を示しました:-)

すべてのテーブルで実行する必要があるクエリ:

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

他のすべてのクエリを生成するクレイジークエリ:

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

1つのデータベースで実行したかっただけです。すべてを1つのパスで実行するには時間がかかりすぎていました。テーブルごとにフィールドごとに1つのクエリを生成していることがわかりました。そして、テーブルごとに1つのクエリのみが必要でした(救助とは異なります)。ファイルの出力を取得することは、私がそれを実現した方法でした。

ファイルへの出力を生成する方法:

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

そして最後に、すべてのクエリを実行します。

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

リチャードに感謝します。あなたは男です!

20

まず第一に、ただ私の言葉をそのために受け取らないでください!これで私の提案をテストしてください:

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;

その結果に満足したら、制限句を削除して、出力をSQLスクリプトに保存するか、空想を得て、出力をmysqlに直接パイプして、 here のようにします。これは次のようになります。

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

有効なSQLを使用して有効なSQLを生成することを考え始めると、ゲーム全体が変わります。あなたはそれのためにあなたが見つける多くの用途に驚かれることでしょう。

16
Bruno Bronosky

実際、テーブルでCONVERT TOを使用して、テーブル内のすべての列を文字セットと照合に変換することができます。

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

また、これを実行する実際のデータベースを選択する方が私には理にかなっています。したがって、この:

... WHERE TABLE_SCHEMA = 'databasename';

これではなく:

... WHERE TABLE_SCHEMA != 'information_schema';

しかし、あなたがreallyをすべてのテーブルで実行したい場合は、前者を使用できます。私に少し手渡されたようですが。 :)

6
user51876

使用したすべての列の照合順序を変更するには

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

information_schemaデータベースを変更して、変更する必要がある列とテーブルを見つけます。あなたはそれらを見つけることができます:

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

次に、SQLスクリプト、ストアプロシージャ、または任意の開発言語を使用して変更を自動化できます。

0
lg.

私は次のようにしてしまいました:

  • mysqldump db_name > db_name.sqlを使用して、データベースをSQLファイルにダンプしました
  • awk sed -i -e 's/old_charset/new_charset/g' db_name.sqlを使用してSQLファイルの文字セットを置き換えます
  • この新しいデータベースファイルをインポートしますmysql < db_name

これは本番環境では使用しませんが、ローカルの開発環境で必要でした。

あるいは、SQL構造とデータを別々にダンプしてから、SQLファイルに移動して文字セットを変更することもできます。

互換性のない文字セット間で変換する場合、データがめちゃくちゃになる可能性があることに注意してください。

0
Nebojsac