[英]Update all blob columns in all tables in MySQL
我们正在将 wiki 系统从 MediaWiki v1.25 迁移到 v1.35,同时在同一 MySQL 服务器中使用克隆数据库,但在新的 Apache 服务器中。 问题是,在完成此处和此处提到的所有步骤之后,所有具有 UTF-8 编码字符(如 á、Ó、é)的 BLOB 列都被 UTF-8 编码字符U+0083污染,就在前面提到的字符之前。 幸运的是,我们发现它可以通过执行以下UPDATE
来解决。
UPDATE clone_wiki_db.some_table
SET blob_col = REPLACE(blob_col, CONCAT(CHAR(0x83), CHAR(0xC2)), '');
这里的问题是数据库中有很多 BLOB 列。 有没有办法批量UPDATE
克隆数据库中的所有 BLOB 列? 有没有更好的方法来进行这种“清洁”?
以下是这两个系统的一些细节:
旧系统(这里没有问题)
新系统(在测试阶段,有问题)
如果有人遇到同样的情况,请自行回答。 基于这个答案,我使用了一个存储过程,一个 cursor 和一个准备好的语句来完成这项工作。 首先,我检索数据库中具有BLOB
、 TINYBLOB
或VARBINARY
数据类型的所有列以及相应的表。 然后,通过使用CURSOR
,我获取每一行并构建一个动态UPDATE
字符串,以便使用准备好的语句/动态 SQL 执行它。
DELIMITER //
DROP PROCEDURE IF EXISTS BLOB_CLEANER//
CREATE PROCEDURE BLOB_CLEANER() BEGIN
DECLARE var_final INTEGER DEFAULT 0;
DECLARE var_column VARCHAR(25);
DECLARE var_table VARCHAR(25);
DECLARE cursor1 CURSOR FOR
SELECT TABLE_NAME,
COLUMN_NAME
FROM INFORMATION_SCHEMA.columns
WHERE TABLE_SCHEMA = 'clone_wiki_db'
AND DATA_TYPE IN ('TINYBLOB', 'BLOB', 'VARBINARY');
DECLARE CONTINUE HANDLER FOR NOT FOUND SET var_final = 1;
OPEN cursor1;
bucle: LOOP
FETCH cursor1
INTO var_table,
var_column;
IF (var_final = 1) THEN
LEAVE bucle;
END IF;
SET @sql = CONCAT(
'UPDATE ',
var_table,
' SET ',
var_column,
' = REPLACE(',
var_column,
', CONCAT(CHAR(0x83), CHAR(0xC2)), '''')'
);
PREPARE stmt
FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP bucle;
CLOSE cursor1;
END//
DELIMITER ;
执行 SP 后,我将 DB 的字符集从 latin1 更改为 utf8_swedish_ci。
ALTER SCHEMA `clone_wiki_db` DEFAULT COLLATE utf8_swedish_ci;
最后,重启Apache服务。
与往常一样,在使用动态 SQL(或类似这样的准备好的语句)时要小心,以避免 SQL 注入。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.