批量修改mysql表、表、數據庫的字符校對規則

記錄一個在工做中遇到的問題,也不算是問題,爲的是找一種簡便的方法批量修改數據表字段的排序規則,在MySQL中叫collation,經常和編碼CHARACTER一塊兒出現的。collation有三種級別,分辨是數據庫級別,數據表級別和字段級別。sql

1.The database level
2.The table level
3.The column level

https://confluence.atlassian.com/display/CONFKB/How+to+Fix+the+Collation+and+Character+Set+of+a+MySQL+Database 這篇文章說得比較詳細。數據庫

那天遇到的問題是這樣子的,
Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '=',主要是由於遷移數據庫時候沒有把collation規則及時修改過來。segmentfault

網上搜到的解決辦法,都提到了修改數據表級別collation排序規則。可是我遇到的場景是數據表級別已是utf8_unicode_ci,而字段級別是utf8_general_ci,(這裏咱們關心的字段類型是varchar)。網絡

因爲須要修改的字段太多了,手工修改確定是費時費力的。天然也想到了用腳本的方式批量修改,可是發現這種經過查找MySQL信息表、過濾、拼接生成批量修改的語句太好用了,並且還能作到針對varchar類型。編碼

SELECT CONCAT('ALTER TABLE `', table_name, '` MODIFY `', column_name, '` ', DATA_TYPE, '(', CHARACTER_MAXIMUM_LENGTH, ') CHARACTER SET UTF8 COLLATE utf8_unicode_ci', (CASE WHEN IS_NULLABLE = 'NO' THEN ' NOT NULL' ELSE '' END), ';')FROM information_schema.COLUMNSWHERE TABLE_SCHEMA = 'database'AND DATA_TYPE = 'varchar'AND(
    CHARACTER_SET_NAME != 'utf8'
    OR
    COLLATION_NAME != 'utf8_unicode_ci');

database須要改爲實際數據庫名字。須要注意的是,若是要修改的字段存在外鍵關係,那就要當心處理,刪除外鍵,修改collation後再把外鍵關係加回來。spa

摘自http://segmentfault.com/a/1190000002570642code

==========================以上網絡引用,下面內容是我修改後的SQL,感謝鄭同窗幫忙=======================================orm

-- 修改數據庫表校對規則SQL,執行時將表中列的校對規則一併修改。
delimiter//
drop procedure if exists `alter_table_character` //-- 若已存在則刪除
create procedure `alter_table_character`() 
begin
    declare f_name varchar(100); 
    declare b int default 0;    /*是否達到記錄的末尾控制變量*/
		-- 注意修改下面的數據庫名稱 wsm_aliyun
    declare table_name cursor for SELECT TABLE_NAME FROM information_schema.TABLES where TABLE_SCHEMA = 'wsm_aliyun' and TABLE_NAME like 'wsm_%' AND TABLE_COLLATION = 'utf8_unicode_ci';    
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET b = 1;
   
    OPEN table_name;
    REPEAT
    FETCH table_name INTO f_name; /*獲取第一條記錄*/
				SET @STMT :=CONCAT("ALTER TABLE ",f_name," CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;");   
			PREPARE STMT FROM @STMT;   
    EXECUTE STMT;  
-- INSERT into TestTable(name) VALUES (f_name);
       -- ALTER TABLE f_name CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; 
    UNTIL b = 1
		END REPEAT;
    close table_name;        
end;
//
/*切換回系統默認的命令結束標誌*/
delimiter ;
-- 執行存儲過程
call alter_table_character();
-- 修改數據庫的校對規則
set names 'utf8' collate 'utf8_general_ci';

-- 查詢修改的結果,其實還能夠用下面的語句生成相應的SQL,執行這個SQL來完成修改,固然沒有上面的存儲過程效率高。

-- 查看數據庫的校對規則,結果全都爲:utf8_general_ci,表示已修改
show variables like 'collation_%';
-- 查看數據庫的校對規則,沒有數據代表已所有修改。
SELECT
	CONCAT('alter table ', TABLE_NAME, ' CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;') as new_sql
FROM
	INFORMATION_SCHEMA.TABLES
WHERE
	TABLE_SCHEMA = 'wsm_aliyun'
AND TABLE_NAME LIKE 'wsm_%' -- 數據庫名稱
AND TABLE_COLLATION = 'utf8_unicode_ci';


-- 查詢列結果,沒有數據代表已所有修改。
SELECT
	CONCAT(
		'ALTER TABLE `',
		table_name,
		'` MODIFY `',
		column_name,
		'` ',
		DATA_TYPE,
		'(',
		CHARACTER_MAXIMUM_LENGTH,
		') CHARACTER SET UTF8 COLLATE utf8_general_ci;'
	) as new_sql
FROM
	information_schema.COLUMNS
WHERE
	TABLE_SCHEMA = 'wsm_aliyun' -- 數據庫名
AND TABLE_NAME LIKE 'wsm_%'
AND DATA_TYPE = 'varchar'
AND CHARACTER_SET_NAME = 'utf8'
AND COLLATION_NAME = 'utf8_unicode_ci';
相關文章
相關標籤/搜索