繁体   English   中英

更新 MySQL 中所有表中的所有 blob 列

[英]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 列? 有没有更好的方法来进行这种“清洁”?

以下是这两个系统的一些细节:

旧系统(这里没有问题)

  • 媒体维基 1.25
  • MySQL 5.6.29
    • 原始数据库,未以任何方式更改。
  • PHP 5.4.45
  • CentOS 5

新系统(在测试阶段,有问题)

  • 媒体维基 1.35
  • MySQL 5.6.29 (稍后更新)
    • 克隆数据库
    • 与原始字符集相同
  • PHP 7.4.30
  • CentOS 8 Stream

如果有人遇到同样的情况,请自行回答。 基于这个答案,我使用了一个存储过程,一个 cursor 和一个准备好的语句来完成这项工作。 首先,我检索数据库中具有BLOBTINYBLOBVARBINARY数据类型的所有列以及相应的表。 然后,通过使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM