如何将数据库中的所有表转换为一个排序规则?

lis*_*aro 62 mysql sql

我收到错误:

操作'='的非法混合排序(utf8_general_ci,IMPLICIT)和(utf8_unicode_ci,IMPLICIT)

我尝试手动更改两个表,utf8_general_ci,IMPLICIT但我仍然收到错误.

有没有办法将所有表转换为utf8_general_ci,IMPLICIT并完成它?

Nam*_*ian 138

您需要为每个表执行alter table语句.该声明将遵循以下形式:

ALTER TABLE tbl_name
[[DEFAULT] CHARACTER SET charset_name]
[COLLATE collation_name]
Run Code Online (Sandbox Code Playgroud)

现在要获取数据库中的所有表,您需要执行以下查询:

SELECT * 
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="YourDataBaseName"
AND TABLE_TYPE="BASE TABLE";
Run Code Online (Sandbox Code Playgroud)

所以现在让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";
Run Code Online (Sandbox Code Playgroud)

您可以复制结果并执行它们.我没有测试语法,但你应该能够弄清楚其余部分.把它想象成一个小练习.

希望有所帮助!

  • 对于寻找快速完美解决方案的人,我使用以下代码来处理表名是可能的关键字,当然还有使用分号:)`CONCAT("ALTER TABLE \`",TABLE_NAME,"\`CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci ;")` (5认同)
  • 我用`SELECT GROUP_CONCAT(ExecuteTheString SEPARATOR'')FROM(....)t`包装了这个查询,这样我就可以在phpMyAdmin中更容易地抓取所有表. (2认同)

Flo*_*ing 49

更好的选项也可以更改表中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"
Run Code Online (Sandbox Code Playgroud)

另外,如果你在启动束脚本之前在非utf8列上有forein键的数据

SET foreign_key_checks = 0;
Run Code Online (Sandbox Code Playgroud)

这意味着全局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;
Run Code Online (Sandbox Code Playgroud)

但是如果根据mysql文档http://dev.mysql.com/doc/refman/5.1/en/charset-column.html,请注意,

如果使用ALTER TABLE将列从一个字符集转换为另一个字符集,则MySQL会尝试映射数据值,但如果字符集不兼容,则可能会丢失数据."

编辑:特别是列类型枚举,它只是崩溃completly枚举集(即使没有特殊的字符) https://bugs.mysql.com/bug.php?id=26731


dGo*_*dGo 22

@ 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";
Run Code Online (Sandbox Code Playgroud)

  • 我用你的代码成功了,谢谢。我建议添加外键检查启用/禁用,并在表键周围添加引号。 (3认同)
  • 无需单独执行列,因为“ALTER TABLE CONVERT TO CHARACTER SET”会自动转换所有列 (2认同)

Pan*_*kaj 18

以下是更准确的查询.我举例说明如何将其转换为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"
Run Code Online (Sandbox Code Playgroud)


Min*_*eam 11

如果您使用的是 PhpMyAdmin,您现在可以:

  1. 选择数据库。
  2. 单击“操作”选项卡。
  3. 在“排序规则”部分下,选择所需的排序规则。
  4. 单击“更改所有表排序规则”复选框。
  5. 将出现一个新的“更改所有表列排序规则”复选框。
  6. 单击“更改所有表列排序规则”复选框。
  7. 单击“开始”按钮。

我有超过 250 张表要转换。花了5分钟多一点。

  • 谢谢。这应该是最重要的答案! (2认同)

小智 7

您可以使用此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
Run Code Online (Sandbox Code Playgroud)


小智 6

对于 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"
Run Code Online (Sandbox Code Playgroud)

只需更改您的tableschemaname 就可以了。