MySQL:同一列中的混合编码

标签 mysql encoding utf-8 cp1251 cp866

我使用 OCS Inventory 清点我们的 PC。它几乎可以正常工作,但是……但是这些 PC 中有 99% 可以在 Windows(R):XP 和 7 下运行。而且 WMI 信息没有任何标准。

例如,OCS Agent(目标 PC 上的驻留程序,收集数据并将其发送到 OCS 服务器)可能会收到“Realtek PCIe GBE Family Controller (1 Gb/s)”(纯英语,编码不是问题),或作为“¨£ ¡¨â®¥ á¥â¥¢®¥ ¯®¤ª«î票¥ Intel(R) 82566DM-2 (100 Mb/s)”(不正确,俄语,CP1251),或“Realtek RTL8169/8110 系列千兆以太网 NIC - Ìèíèïîðò ïëàíèðîâùèêà ïàêåòîâ (100 Mb/s)”(不正确,俄语,CP866 ).或“VIA Rhine III 快速以太网适配器 - Минипорт планировщика пакетов (100 Mb/s)”(正确,俄语,UTF8 或其他 Unicode)

我没有办法让 Windows 仅以一种编码返回这些结果:这似乎取决于驱动程序制造商的想法:驱动程序的 .INF 文件中使用了哪种编码,WMI 将返回该编码。

大多数情况下这不是问题,但我的老板们非常不喜欢在有关我们 IT 基础架构状态的季度报告中看到“象形文字”。他们似乎是对的。

有没有办法将单个字段从一种编码重新编码为另一种编码?由于内容混合,我不会重新编码整个专栏。我可以大致确定使用了哪种编码,但我不知道如何仅使用 MySQL 的 SQL 语言重新编码以生成正确的报告。

有什么工作建议吗?

最佳答案

看起来唯一的方法就是编写存储过程。我做到了。 左栏(castbin)是处理前的文本,右栏(converted)是处理后的相同文本

enter image description here

看代码

...
#above and below are regular MySQL statements
@castbin:=cast(networks.description as char character set binary) as castbin,
@convv:=convert(repcxaxex(@castbin) using cp866) as converted
...

@castbin 变量仅用于说明和可读性。 repCxAxEx 函数完成的所有工作,以“用 0xCx 0xEx 替换 0xCx 0xAx”命名。这是此函数的非常不理想但有效的代码(取自 MySQL Studio)

See corrected text of the function below in update section

首先我们查看字符串是否可转换,然后进行两次转换 - 针对 0xC20xC3 前缀,因为这些前缀意味着不同的编码错误。

更新: 彻底的测试发现了一些错误。

在查询中的某处,我使用 group_concat 运算符将同一台 PC 的多个属性的值合并为一个长字符串,以“\n”作为分隔符。在这种情况下,转换可能无法进行。

-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$

CREATE DEFINER=`root`@`%` FUNCTION `repcxaxex`(s2c text charset binary) RETURNS blob
begin
/*исправляем проблемы с кодировками*/
    set @i:=0;
    set @s:=s2c;
    set @altered:='0';
    if ((left(@s,1)=char(0xc2)) or instr(@s,char(32,0xc2)) or instr(@s,char(0x0a,0xc2))) then
    while @i<16 do
        set @s:=replace(@s,char(0xc3,(160+@i)),char(0xd3,(224+@i)));
        set @i:=@i+1;
    end while;
    set @i:=1;
    while @i<4 do
        set @s:=replace(@s,char(0xc0+@i),'');
        set @s:=replace(@s,char(0xd0+@i),'');
        set @i:=@i+1;
    end while;
    set @altered:='1';
    end if;
    set @i:=0;
    if ((left(@s,1)=char(0xc3)) or instr(@s,char(32,0xc3)) or instr(@s,char(0x0a,0xc3))) then
    while @i<16 do
        set @s:=replace(@s,char(0xc3,(176+@i)),char(0xd3,(224+@i)));
        set @i:=@i+1;
    end while;
    set @i:=1;
    while @i<4 do
        set @s:=replace(@s,char(0xc0+@i),'');
        set @s:=replace(@s,char(0xd0+@i),'');
        set @i:=@i+1;
    end while;
    set @altered:='2';
    end if;
/*Добавляем 0 или 1 в начало строки, чтобы показать, конвертировали ее или нет
выводить надо будет, начиная со второго символа*/
    set @s=concat(@altered,@s);
    return @s;
end

函数退出时,将一位数字添加到返回字符串的开头。数字本身由 @altered 变量确定,其代码不言自明。

更正确的调用形式是:

If (left(repcxaxex(string-to-convert),1)='0',string-to-convert,mid(convert(repcxaxex(string-to-convert) using cp866),2))

关于MySQL:同一列中的混合编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34488009/

相关文章:

MySQL,查找具有另一个匹配参数的双行

mysql - 将大量数据从 XML 文件转换为数据库

mysql - SQL 查询无法检索多个结果

MySQL JOIN 和 COUNT 不一致

php - 使用 PHP 处理 GET 参数中的 unicode 值

java - 使用 UTF-16BE 的 JAXB 空元素过早结束文件

c# - Java 中的等效 GetBytes 函数,如 c#

php - mysql 查询中的文本是否可能不遵守排序规则?

MySql INNER JOIN 查询问题

java - 使用java编写UTF-8文件