看起来唯一的方法是编写存储过程。我做到了。左列(castbin
)为处理前的文本,右列( )为处理converted
后的相同文本
来看看代码
...
#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
首先我们查看字符串是否可转换,然后进行两次转换 - for0xC2
和0xC3
前缀,因为这些前缀意味着不同的编码错误。
更新:彻底的测试发现了一些错误。
在查询的某处,我使用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))