将MySQL的Levenshtein Distance算法转SQL Server遇函数适配问题
解决Levenshtein Distance算法从MySQL转SQL Server的函数替换问题
首先明确你提到的几个MySQL函数在SQL Server中的等效实现:
HEX()+UNHEX():原代码中UNHEX(HEX(@j))是将整数转换为单字节二进制值,SQL Server中直接用CONVERT(varbinary(1), @j)即可完成相同操作,无需先转十六进制再转回二进制。CONV(HEX(SUBSTRING(...)), 16, 10):原逻辑是提取二进制变量的单个字节并转换为十进制整数,SQL Server中直接对提取的二进制字节执行CONVERT(int, SUBSTRING(...))就能得到对应十进制数值,省去中间十六进制转换步骤。CONCAT拼接二进制:SQL Server中CONCAT会自动将二进制转换为字符串,无法正确拼接二进制数据,需改用+运算符实现二进制拼接。
以下是修改后的完整SQL Server函数代码:
CREATE FUNCTION fn_FuzzyMatch( @str1 varchar(max), @str2 varchar(max) ) RETURNS int AS BEGIN DECLARE @str1_len int, @str2_len int, @i int, @j int, @c int, @c_temp int, @cost int, @str1_char char, @cv0 varbinary(max), @cv1 varbinary(max); SELECT @str1_len = LEN(@str1), -- 若SDU_Tools.StringLength是自定义长度函数可保留,否则替换为LEN @str2_len = LEN(@str2), @cv1 = 0x00, @j = 1, @i = 1, @c = 0; IF @str1 = @str2 RETURN 0; ELSE IF @str1_len = 0 RETURN @str2_len; ELSE IF @str2_len = 0 RETURN @str1_len; ELSE BEGIN WHILE @j <= @str2_len BEGIN -- 替换UNHEX(HEX(@j))为CONVERT(varbinary(1), @j),用+拼接二进制 SET @cv1 = @cv1 + CONVERT(varbinary(1), @j); SET @j = @j + 1; END; WHILE @i <= @str1_len BEGIN SELECT @str1_char = SUBSTRING(@str1, @i, 1), @c = @i, -- 替换UNHEX(HEX(@i))为CONVERT(varbinary(1), @i) @cv0 = CONVERT(varbinary(1), @i), @j = 1; WHILE @j <= @str2_len BEGIN SET @c = @c + 1; IF @str1_char = SUBSTRING(@str2, @j, 1) SET @cost = 0; ELSE SET @cost = 1; -- 替换CONV(HEX(...),16,10)为直接转换二进制字节到int SET @c_temp = CONVERT(int, SUBSTRING(@cv1, @j, 1)) + @cost; IF @c > @c_temp SET @c = @c_temp; SET @c_temp = CONVERT(int, SUBSTRING(@cv1, @j+1, 1)) + 1; IF @c > @c_temp SET @c = @c_temp; -- 替换CONCAT和UNHEX(HEX(@c)),用+拼接二进制 SET @cv0 = @cv0 + CONVERT(varbinary(1), @c); SET @j = @j + 1; END; SET @cv1 = @cv0; SET @i = @i + 1; END; END; RETURN @c; END
关键修改点说明:
- 二进制值生成:将
UNHEX(HEX(@j))替换为CONVERT(varbinary(1), @j),直接将整数转换为对应的单字节二进制,逻辑更高效。 - 二进制拼接:用
+替代CONCAT,避免二进制被错误转换为字符串。 - 字节转整数:直接对
SUBSTRING提取的二进制字节执行CONVERT(int, ...),省去MySQL中先转十六进制再转十进制的冗余步骤。
内容的提问来源于stack exchange,提问作者Dizzy49
相关产品推荐
相关产品推荐

