데이터베이스의 모든 테이블을 하나의 데이터 정렬로 변환하는 방법은 무엇입니까?


82

오류가 발생합니다.

'='작업에 대한 데이터 정렬 (utf8_general_ci, IMPLICIT) 및 (utf8_unicode_ci, IMPLICIT)의 잘못된 조합

두 테이블을 수동으로 변경하려고 시도했지만 utf8_general_ci,IMPLICIT여전히 오류가 발생합니다.

모든 테이블을 변환하고 처리하는 방법 utf8_general_ci,IMPLICIT이 있습니까?



답변:


166

각 테이블에 대해 alter table 문을 실행해야합니다. 진술은 다음 형식을 따릅니다.

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;")
브라이언 Leishman을

3
이 쿼리를 SELECT GROUP_CONCAT(ExecuteTheString SEPARATOR ' ') FROM (....) tphpMyAdmin에서 한 번에 더 쉽게 모든 테이블을 가져올 수 있도록 래핑했습니다 .
Zane

MySQL PHPMYAdmin에서 빈 결과를 반환합니다.
Michael

@Michael은 여전히 ​​나를 위해 일합니다. 상황을 반영하도록 매개 변수를 변경 했습니까?
Namphibian 17

@Namphibian nope 난 내 자신의 스키마 및 테이블 유형 (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"

또한 번들 스크립트를 시작하기 전에 utf8이 아닌 열에 forein 키가있는 데이터가있는 경우

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은 데이터 값 매핑을 시도하지만 문자 집합이 호환되지 않으면 데이터가 손실 될 수 있습니다. "

편집 : 특별히 열 유형 enum을 사용하면 완전히 enum이 설정됩니다 (특별한 caracters가 없더라도) 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

1
ALTER TABLE CONVERT TO CHARACTER SET모든 열 을 자동으로 변환 하므로 열을 개별적으로 수행 할 필요가 없습니다.
SystemParadox

잘 작동합니다. 제 경우에는 성공 에 대한 키워드 충돌 (예 : Desc, Password..)을 피하기 위해 테이블 ​​/ 열 이름을 인용해야했습니다 .
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데이터를 테이블
user11153

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

암호 변수를 추가하여 @Petr Stastny의 답변을 한 단계 더 나아가십시오. 인수가 아닌 일반 암호처럼 실제로 가져가는 것이 좋지만 필요한만큼 작동합니다.

#!/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"

테이블 스키마 이름을 변경하면 괜찮습니다.


@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.