Veritabanındaki tüm tabloları bir harmanlamaya nasıl dönüştürebilirim?


82

Hata alıyorum:

'=' "İşlemi için yasa dışı harmanlama karışımı (utf8_general_ci, IMPLICIT) ve (utf8_unicode_ci, IMPLICIT)

Her iki tabloyu da manuel olarak değiştirmeyi denedim utf8_general_ci,IMPLICITama yine de hatayı alıyorum.

Tüm tabloları ona dönüştürmenin utf8_general_ci,IMPLICITve onunla yapılmanın bir yolu var mı ?


Bunu buldum (bazı iyi cevaplar vardı): stackoverflow.com/questions/105572/…
Luke Wyatt

Yanıtlar:


166

Her tablo için bir alter table deyimi yürütmeniz gerekir. İfade şu şekilde olacaktır:

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

Şimdi veritabanındaki tüm tabloları almak için aşağıdaki sorguyu yürütmeniz gerekir:

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

Şimdi MySQL'in sizin için kodu yazmasına izin verin:

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

Sonuçları kopyalayabilir ve çalıştırabilirsiniz. Sözdizimini test etmedim ama gerisini çözebilmelisiniz. Bunu küçük bir egzersiz olarak düşünün.

Umarım yardımcı olur!


7
Hızlı ve mükemmel bir çözüm arayan biri için, olası anahtar kelimeler olan tablo adlarıyla ve elbette noktalı virgül kullanarak çalışmak için aşağıdakileri kullandım :) CONCAT("ALTER TABLE `", TABLE_NAME,"` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;")
Brian Leishman

3
Bu sorguyu SELECT GROUP_CONCAT(ExecuteTheString SEPARATOR ' ') FROM (....) tphpMyAdmin'de tüm tabloları bir kerede daha kolay yakalayabilmek için sardım.
Zane

Bu MySQL PHPMYAdmin'de boş bir sonuç döndürür
Michael

@Michael hala benim için çalışıyor. Durumunuzu yansıtmak için parametreleri değiştirdiniz mi?
Namphibian

@Namphibian hayır, şemayı yalnızca kendi şema ve tablo türümle (InnoDB) değiştiriyorum
Michael

63

Tablonun içindeki varchar sütunlarının harmanlamasını da değiştirmek için daha iyi bir seçenek

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"

Ek olarak, utf8 olmayan sütunda forein anahtarına sahip verileriniz varsa, grup komut dosyasını başlatmadan önce

SET foreign_key_checks = 0;

Bu, global SQL'in mySQL için olacağı anlamına gelir:

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;

Ancak mysql belgelerine göre dikkatli olun http://dev.mysql.com/doc/refman/5.1/en/charset-column.html ,

Bir sütunu bir karakter kümesinden diğerine dönüştürmek için ALTER TABLE kullanırsanız, MySQL veri değerlerini eşlemeye çalışır, ancak karakter kümeleri uyumsuzsa, veri kaybı olabilir. "

DÜZENLEME: Özellikle sütun türü numaralandırmasıyla, yalnızca set numaralandırmalarının tamamen çökmesi (özel karakterler olmasa bile) https://bugs.mysql.com/bug.php?id=26731


27

@ Namphibian'ın önerisi bana çok yardımcı oldu ...
biraz daha ileri gitti ve senaryoya sütunlar ve görünümler ekledi

sadece şemanızın adını aşağıya girin ve gerisini halleder

-- 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
Kodunuzu başarı için kullandım, teşekkürler. Yabancı anahtar kontrolü etkinleştirme / devre dışı bırakma eklemenizi ve ayrıca tablo anahtarlarının etrafına tırnak işaretleri eklemenizi öneririm.
Igor Skoric

1
ALTER TABLE CONVERT TO CHARACTER SETTüm sütunları otomatik olarak dönüştürdüğü için sütunları ayrı ayrı yapmak gerekli değildir
SystemParadox

Harika çalışıyor. Benim durumumda, anahtar kelime çatışmalarını ( Desc, Password.. gibi ) başarıya ulaştırmak için tablo / sütun adlarını alıntı yapmak zorunda kaldım .
deerchao

19

Aşağıda daha doğru sorgu verilmiştir. Utf8'e nasıl dönüştürüleceğine bir örnek veriyorum

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"

İyi, ancak CONVERT TO CHARACTER SETveri içeren tablolar için değiştirmem gerekiyordu
user11153

8

Bu BASH komut dosyasını kullanabilirsiniz:

#!/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 kullanıyorsanız, artık şunları yapabilirsiniz:

  1. Veritabanını seçin.
  2. "İşlemler" sekmesini tıklayın.
  3. "Harmanlama" bölümü altında, istenen harmanlamayı seçin.
  4. "Tüm tablo harmanlamalarını değiştir" onay kutusunu tıklayın.
  5. Yeni bir "Tüm tablo sütunlarının harmanlamalarını değiştir" onay kutusu görünecektir.
  6. "Tüm tablo sütunlarının harmanlamalarını değiştir" onay kutusunu tıklayın.
  7. "Git" düğmesini tıklayın.

Dönüştürmem gereken 250'den fazla tablo vardı. 5 dakikadan biraz fazla sürdü.


4

PhpMyAdmin için şunu anladım:

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"

Sadece masanızın ismini değiştirin ve iyisiniz.


@LucaC. group_concat sınırını artırmanız gerekiyor, örn:set session group_concat_max_len = @@max_allowed_packet;
James

3

Bu benim bir bash betiği versiyonum. Veritabanı adını bir parametre olarak alır ve tüm tabloları başka bir karakter grubuna ve harmanlamaya dönüştürür (başka parametreler veya kodda tanımlanan varsayılan değer tarafından verilir).

#!/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'den cevabı bir şifre değişkeni ekleyerek bir adım daha ileri götürmek. Bir argüman yerine normal bir parola gibi almasını tercih ederim, ama ihtiyacım olan şey için çalışıyor.

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

1

Kopyala-yapıştır bash komut dosyası istiyorsanız:

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'i veritabanı adınızla değiştirin.


1

GH'den sonra, bunu uzak bir sunucuda yapmanız gerekmesi durumunda kullanıcı ve ana bilgisayar parametrelerini ekledim

    #!/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"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.