-- ===================================================================== -- V27 · 修复历史遗留的双重编码中文(通用回转) -- --------------------------------------------------------------------- -- 现象:后台「品类管理」备注、以及「平台类型」字典的名称/备注显示乱码。 -- -- 成因:V22 / V25 迁移执行时,服务器 mysql 客户端 character_set_client 为 latin1 -- (容器 C locale),UTF-8 字节被按 latin1 解读后再存入 utf8mb4 列 -- → 中文双重编码("涂鸦智能" 变成 C3A6C2B6E2809A...)。 -- -- 治本(已完成,后续迁移不会再犯): -- - deploy-all.bat 的 mysql 调用已加 --default-character-set=utf8mb4; -- - V25 / V26 脚本首行已加 SET NAMES utf8mb4。 -- 本脚本负责把历史数据修回来。 -- -- 修法:把 latin1 误解后的字符按 latin1 转回原始字节,再按 utf8mb4 重新解释: -- CONVERT(CAST(CONVERT(col USING latin1) AS BINARY) USING utf8mb4) -- 幂等:仅对仍含双重编码特征(HEX 含 C2xx / C3xx)的值生效,修完不再命中。 -- -- 无存储过程、无 DELIMITER;幂等可重复执行。 -- ===================================================================== SET NAMES utf8mb4; -- ---------- 1) 平台类型字典(V22 写入;表可能不存在,做存在性判断) ---------- SET @has_pt = (SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'platform_type'); SET @s = IF(@has_pt > 0, 'UPDATE platform_type SET name = CONVERT(CAST(CONVERT(name USING latin1) AS BINARY) USING utf8mb4), remark = CONVERT(CAST(CONVERT(remark USING latin1) AS BINARY) USING utf8mb4), update_time = NOW() WHERE deleted = 0 AND (HEX(IFNULL(name, '''')) REGEXP ''C[23][0-9A-F]{2}'' OR HEX(IFNULL(remark, '''')) REGEXP ''C[23][0-9A-F]{2}'')', 'SELECT ''platform_type table not found, skipped'' AS info'); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- ---------- 2) 品类字典备注(V25 回填历史品类时写入) ---------- UPDATE product_category SET remark = CONVERT(CAST(CONVERT(remark USING latin1) AS BINARY) USING utf8mb4), update_time = NOW() WHERE deleted = 0 AND HEX(IFNULL(remark, '')) REGEXP 'C[23][0-9A-F]{2}';