データベース内のすべてのテーブルを1つの照合に変換するにはどうすればよいですか?


82

エラーが発生します:

操作 '=' "の照合(utf8_general_ci、IMPLICIT)と(utf8_unicode_ci、IMPLICIT)の不正な組み合わせ

両方のテーブルを手動でに変更しようとしましたutf8_general_ci,IMPLICITが、それでもエラーが発生します。

すべてのテーブルをに変換して実行する方法はありutf8_general_ci,IMPLICITますか?


これを見つけました(いくつかの良い答えがありました): stackoverflow.com/questions/105572/…–
ルークワイアット

回答:


166

テーブルごとにaltertableステートメントを実行する必要があります。ステートメントは次の形式に従います。

ALTER TABLE tbl_name
[[DEFAULT] CHARACTER SET charset_name]
[COLLATE collation_name]

データベース内のすべてのテーブルを取得するには、次のクエリを実行する必要があります。

SELECT * 
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="YourDataBaseName"
AND TABLE_TYPE="BASE TABLE";

では、MySQLにコードを書かせてください。

SELECT CONCAT("ALTER TABLE ", TABLE_SCHEMA, '.', TABLE_NAME," COLLATE your_collation_name_here;") AS    ExecuteTheString
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="YourDatabaseName"
AND TABLE_TYPE="BASE TABLE";

結果をコピーして実行できます。私は構文をテストしていませんが、残りを理解できるはずです。ちょっとした練習だと思ってください。

お役に立てば幸いです。


7
迅速で完璧な解決策を探している人のために、私は以下を使用して、可能なキーワードであるテーブル名を操作し、もちろんセミコロンを使用しました:) CONCAT("ALTER TABLE `", TABLE_NAME,"` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;")
Brian Leishman 2015年

3
SELECT GROUP_CONCAT(ExecuteTheString SEPARATOR ' ') FROM (....) tphpMyAdminですべてのテーブルを一度に簡単に取得できるように、このクエリをでラップしました。
ゼーン2016年

これにより、MySQL PHPMYAdminに空の結果が返されます
Michael

@Michaelはまだ私のために働いています。状況を反映するようにパラメーターを変更しましたか?
ナンフィビアン2017年

@Namphibianいいえ、スキーマを自分のスキーマとテーブルタイプ(InnoDB)に置き換えるだけです
Michael

63

テーブル内のvarchar列の照合も変更するためのより良いオプション

SELECT CONCAT('ALTER TABLE `', TABLE_NAME,'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;') AS    mySQL
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA= "myschema"
AND TABLE_TYPE="BASE TABLE"

さらに、bunchスクリプトを起動する前に、utf8以外の列にフォアインキーを持つデータがある場合は、

SET foreign_key_checks = 0;

これは、グローバルSQLがmySQL用になることを意味します。

SET foreign_key_checks = 0;
ALTER TABLE `table1` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE `table2` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE `tableXXX` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
SET foreign_key_checks = 1;

ただし、mysqlのドキュメントhttp://dev.mysql.com/doc/refman/5.1/en/charset-column.htmlに従って、注意してください。

ALTER TABLEを使用して列をある文字セットから別の文字セットに変換する場合、MySQLはデータ値をマップしようとしますが、文字セットに互換性がない場合、データが失われる可能性があります。「」

編集:特に列タイプの列挙型では、列挙型セットが完全にクラッシュします(特別な文字がない場合でも) https://bugs.mysql.com/bug.php?id=26731


27

@Namphibianの提案は私を大いに助けました...
しかし少し進んで、スクリプトに列とビューを追加しました

以下にスキーマの名前を入力するだけで、後は自動的に実行されます

-- set your table name here
SET @MY_SCHEMA = "";

-- tables
SELECT DISTINCT
    CONCAT("ALTER TABLE ", TABLE_NAME," CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;") as queries
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA=@MY_SCHEMA
  AND TABLE_TYPE="BASE TABLE"

UNION

-- table columns
SELECT DISTINCT
    CONCAT("ALTER TABLE ", C.TABLE_NAME, " CHANGE ", C.COLUMN_NAME, " ", C.COLUMN_NAME, " ", C.COLUMN_TYPE, " CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;") as queries
FROM INFORMATION_SCHEMA.COLUMNS as C
    LEFT JOIN INFORMATION_SCHEMA.TABLES as T
        ON C.TABLE_NAME = T.TABLE_NAME
WHERE C.COLLATION_NAME is not null
    AND C.TABLE_SCHEMA=@MY_SCHEMA
    AND T.TABLE_TYPE="BASE TABLE"

UNION

-- views
SELECT DISTINCT
    CONCAT("CREATE OR REPLACE VIEW ", V.TABLE_NAME, " AS ", V.VIEW_DEFINITION, ";") as queries
FROM INFORMATION_SCHEMA.VIEWS as V
    LEFT JOIN INFORMATION_SCHEMA.TABLES as T
        ON V.TABLE_NAME = T.TABLE_NAME
WHERE V.TABLE_SCHEMA=@MY_SCHEMA
    AND T.TABLE_TYPE="VIEW";

3
私はあなたのコードを成功に使用しました、ありがとう。外部キーチェックの有効化/無効化を追加し、テーブルキーを引用符で囲むことをお勧めします。
Igor Skoric 2017年

1
ように、個別の列を行う必要はありませんALTER TABLE CONVERT TO CHARACTER SET、自動的にすべての列を変換
SystemParadox

よく働く。私の場合、成功するためにキーワードの競合(DescPassword..など)を回避するためにテーブル/列名を引用する必要がありました。
deerchao

19

以下は、より正確なクエリです。私はそれをutf8に変換する方法の例を挙げています

SELECT CONCAT("ALTER TABLE `", TABLE_NAME,"` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;") AS    mySQL
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="myschema"
AND TABLE_TYPE="BASE TABLE"

良いですが、CONVERT TO CHARACTER SETデータを含むテーブル用に変更する必要がありました
user111 5319年

8

このBASHスクリプトを使用できます。

#!/bin/bash

USER="YOUR_DATABASE_USER"
PASSWORD="YOUR_USER_PASSWORD"
DB_NAME="DATABASE_NAME"
CHARACTER_SET="utf8" # your default character set
COLLATE="utf8_general_ci" # your default collation

tables=`mysql -u $USER -p$PASSWORD -e "SELECT tbl.TABLE_NAME FROM information_schema.TABLES tbl WHERE tbl.TABLE_SCHEMA = '$DB_NAME' AND tbl.TABLE_TYPE='BASE TABLE'"`

for tableName in $tables; do
    if [[ "$tableName" != "TABLE_NAME" ]] ; then
        mysql -u $USER -p$PASSWORD -e "ALTER TABLE $DB_NAME.$tableName DEFAULT CHARACTER SET $CHARACTER_SET COLLATE $COLLATE;"
        echo "$tableName - done"
    fi
done

7

PhpMyAdminを使用している場合は、次のことができます。

  1. データベースを選択します。
  2. 「操作」タブをクリックします。
  3. [照合順序]セクションで、目的の照合順序を選択します。
  4. [すべてのテーブルの照合順序を変更する]チェックボックスをクリックします。
  5. 新しい[すべてのテーブルの列の照合順序を変更する]チェックボックスが表示されます。
  6. [すべてのテーブルの列の照合順序を変更する]チェックボックスをクリックします。
  7. 「実行」ボタンをクリックします。

変換するテーブルが250以上ありました。5分強かかりました。


3

これは私のバージョンのbashスクリプトです。データベース名をパラメーターとして受け取り、すべてのテーブルを別の文字セットと照合順序に変換します(別のパラメーターまたはスクリプトで定義されたデフォルト値によって指定されます)。

#!/bin/bash

# mycollate.sh <database> [<charset> <collation>]
# changes MySQL/MariaDB charset and collation for one database - all tables and
# all columns in all tables

DB="$1"
CHARSET="$2"
COLL="$3"

[ -n "$DB" ] || exit 1
[ -n "$CHARSET" ] || CHARSET="utf8mb4"
[ -n "$COLL" ] || COLL="utf8mb4_general_ci"

echo $DB
echo "ALTER DATABASE $DB CHARACTER SET $CHARSET COLLATE $COLL;" | mysql

echo "USE $DB; SHOW TABLES;" | mysql -s | (
    while read TABLE; do
        echo $DB.$TABLE
        echo "ALTER TABLE $TABLE CONVERT TO CHARACTER SET $CHARSET COLLATE $COLL;" | mysql $DB
    done
)

3

パスワード変数を追加して、@ PetrStastnyからの回答をさらに一歩進めます。引数としてではなく、実際に通常のパスワードのように取り込んだほうがいいのですが、必要なときに機能します。

#!/bin/bash

# mycollate.sh <database> <password> [<charset> <collation>]
# changes MySQL/MariaDB charset and collation for one database - all tables and
# all columns in all tables

DB="$1"
PW="$2"
CHARSET="$3"
COLL="$4"

[ -n "$DB" ] || exit 1
[ -n "$PW" ]
[ -n "$CHARSET" ] || CHARSET="utf8mb4"
[ -n "$COLL" ] || COLL="utf8mb4_bin"

PW="--password=""$PW"

echo $DB
echo "ALTER DATABASE $DB CHARACTER SET $CHARSET COLLATE $COLL;" | mysql -u root "$PW"

echo "USE $DB; SHOW TABLES;" | mysql -s "$PW" | (
    while read TABLE; do
        echo $DB.$TABLE
        echo "ALTER TABLE $TABLE CONVERT TO CHARACTER SET $CHARSET COLLATE $COLL;" | mysql "$PW" $DB
    done
)

PW="pleaseEmptyMeNow"

3

phpMyAdminの場合、私はこれを理解しました。

SELECT GROUP_CONCAT("ALTER TABLE ", TABLE_SCHEMA, '.', TABLE_NAME," CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" SEPARATOR ' ') AS    OneSQLString
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="yourtableschemaname"
AND TABLE_TYPE="BASE TABLE"

tableschemanameを変更するだけで、問題ありません。


@LucaC。group_concatの制限を増やす必要があります。例:set session group_concat_max_len = @@max_allowed_packet;
James

1

コピーアンドペーストのbashスクリプトが必要な場合:

var=$(mysql -e 'SELECT CONCAT("ALTER TABLE ", TABLE_NAME," CONVERT TO CHARACTER SET utf8 COLLATE utf8_czech_ci;") AS execTabs FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA="zabbix" AND TABLE_TYPE="BASE TABLE"' -uroot -p )

var+='ALTER DATABASE zabbix CHARACTER SET utf8 COLLATE utf8_general_ci;'

echo $var | cut -d " " -f2- | mysql -uroot -p zabbix

zabbixをデータベース名に変更します。


1

GHに続いて、リモートサーバーでこれを行う必要がある場合に備えて、ユーザーとホストのパラメーターを追加しました

    #!/bin/bash

    # mycollate.sh <database> <user> <password> [<host> <charset> <collation>]
    # changes MySQL/MariaDB charset and collation for one database - all tables and
    # all columns in all tables

    DB="$1"
    USER="$2"
    PW="$3"
    HOST="$4"
    CHARSET="$5"
    COLL="$6"

    [ -n "$DB" ] || exit 1
    [ -n "$USER" ] || exit 1
    [ -n "$PW" ] || exit 1
    [ -n "$HOST" ] || HOST="localhost"
    [ -n "$CHARSET" ] || CHARSET="utf8mb4"
    [ -n "$COLL" ] || COLL="utf8mb4_general_ci"

    PW="--password=""$PW"
    HOST="--host=""$HOST"
    USER="--user=""$USER"

    echo $DB
    echo "ALTER DATABASE $DB CHARACTER SET $CHARSET COLLATE $COLL;" | mysql "$HOST" "$USER" "$PW"

    echo "USE $DB; SHOW TABLES;" | mysql  "$HOST" "$USER" "$PW" | (
        while read TABLE; do
            echo $DB.$TABLE
            echo "ALTER TABLE $TABLE CONVERT TO CHARACTER SET $CHARSET COLLATE $COLL;" | mysql  "$HOST" "$USER" "$PW" $DB
        done
    )

    PW="pleaseEmptyMeNow"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.