Otrzymuję błąd:
Niedozwolona kombinacja zestawień (utf8_general_ci, IMPLICIT) i (utf8_unicode_ci, IMPLICIT) dla operacji '=' "
Próbowałem ręcznie zmienić obie tabele, utf8_general_ci,IMPLICIT
ale nadal pojawia się błąd.
Czy istnieje sposób, aby przekonwertować wszystkie tabele utf8_general_ci,IMPLICIT
i skończyć z tym?
Odpowiedzi:
Musisz wykonać instrukcję alter table dla każdej tabeli. Oświadczenie miałoby następującą postać:
ALTER TABLE tbl_name [[DEFAULT] CHARACTER SET charset_name] [COLLATE collation_name]
Teraz, aby uzyskać wszystkie tabele w bazie danych, musisz wykonać następujące zapytanie:
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA="YourDataBaseName" AND TABLE_TYPE="BASE TABLE";
Więc teraz pozwól MySQL napisać kod za Ciebie:
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";
Możesz skopiować wyniki i wykonać je. Nie testowałem składni, ale powinieneś być w stanie rozgryźć resztę. Potraktuj to jako małe ćwiczenie.
Mam nadzieję, że to pomoże!
źródło
CONCAT("ALTER TABLE `", TABLE_NAME,"` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;")
SELECT GROUP_CONCAT(ExecuteTheString SEPARATOR ' ') FROM (....) t
aby móc łatwiej pobrać wszystkie tabele naraz w phpMyAdmin.Lepszą opcją jest zmiana również sortowania kolumn varchar w tabeli
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"
Dodatkowo, jeśli masz dane z kluczem forein w kolumnie innej niż utf8 przed uruchomieniem użycia skryptu grupowego
SET foreign_key_checks = 0;
Oznacza to, że globalny SQL będzie dla 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;
Ale uważaj, jeśli zgodnie z dokumentacją mysql http://dev.mysql.com/doc/refman/5.1/en/charset-column.html ,
EDYCJA: Szczególnie w przypadku wyliczenia typu kolumny, po prostu następuje awaria zestawu wyliczeń (nawet jeśli nie ma specjalnych znaków) https://bugs.mysql.com/bug.php?id=26731
źródło
Sugestia @ Namphibian bardzo mi pomogła ...
poszła jednak trochę dalej i dodała kolumny i widoki do skryptu
po prostu wprowadź poniżej nazwę schematu, a on zajmie się resztą
-- 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";
źródło
ALTER TABLE CONVERT TO CHARACTER SET
automatycznie konwertuje wszystkie kolumnyDesc
,Password
..) do sukcesu.Poniżej znajduje się dokładniejsze zapytanie. Podaję przykład, jak przekonwertować go na 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"
źródło
CONVERT TO CHARACTER SET
dla tabel z danymiMożesz użyć tego skryptu 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
źródło
Jeśli używasz PhpMyAdmin, możesz teraz:
Miałem do konwersji ponad 250 tabel. Zajęło to trochę ponad 5 minut.
źródło
W przypadku phpMyAdmin odkryłem to:
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"
Po prostu zmień swoją nazwę tabeli i wszystko w porządku.
źródło
set session group_concat_max_len = @@max_allowed_packet;
To jest moja wersja skryptu bash. Pobiera nazwę bazy danych jako parametr i konwertuje wszystkie tabele na inny zestaw znaków i sortowanie (podane przez inne parametry lub wartość domyślną zdefiniowaną w skrypcie).
#!/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 )
źródło
Idąc o krok dalej z odpowiedzią @Petr Stastny, dodając zmienną hasła. Wolałbym, żeby faktycznie przyjęło to jak zwykłe hasło, a nie jako argument, ale działa na to, czego potrzebowałem.
#!/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"
źródło
Jeśli chcesz skopiować i wkleić skrypt 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
Zmień zabbix na nazwę swojej bazy danych.
źródło
W następstwie GH dodałem parametry użytkownika i hosta na wypadek, gdybyś musiał to zrobić na zdalnym serwerze
#!/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"
źródło