我在MySQL中有一个非常大的表。我正在使用CHAR(32)字段,其中包含MD5作为字符串。我遇到了一个需要使用MySQL将其转换为十进制值的问题。第三方工具运行查询,因此编写代码来执行此操作实际上不是一种选择。
MySQL确实支持本机存储十六进制值并将它们转换为整数。但它会挂起来从字符串中转换它。这是我到目前为止所尝试的内容(md5_key是我的专栏名称)
首先我只是尝试了UNHEX函数,但它返回一个字符串,所以它给了我gooblygoop。我不会把它放在这里。接下来我尝试了CAST功能
SELECT CAST( CONCAT('0x',md5_key) AS UNSIGNED ) FROM bigtable limit 1
结果= 0 显示警告给我:“截断的INTEGER值不正确:'0x000002dcc38af6f209e91518db3e79d3'”
但如果我这样做:
SELECT CAST( 0x000002dcc38af6f209e91518db3e79d3 AS UNSIGNED );
我得到正确的十进制值。
所以我想我需要知道的是,有没有办法让MySQL将该字符串视为十六进制值? (我也尝试将其转换为BINARY,然后转换为UNSIGNED,但这也无效)。
提前致谢!
答案 0 :(得分:5)
conv()仅限于64位整数。您可以将高和低部分转换为十进制,然后将它们一起添加:
> select cast(conv(substr("000002dcc38af6f209e91518db3e79d3", 1, 16), 16, 10) as
decimal(65))*18446744073709551616 +
cast(conv(substr("000002dcc38af6f209e91518db3e79d3", 17, 16), 16, 10) as
decimal(65));
58055532535286745202684464101843
其中18446744073709551616 = 2 ^ 64。所以在你的情况下:
> select cast(conv(substr(md5_key, 1, 16), 16, 10) as
decimal(65))*18446744073709551616 +
cast(conv(substr(md5_key, 17, 16), 16, 10) as
decimal(65))
from bigtable limit 1;
答案 1 :(得分:1)
当心MD5是16字节长,BIGINT UNSIGNED是8字节长,所以即使在你的第二种情况下你没有得到正确的答案,数字不适合你正在接收最低8字节的值= > 09e91518db3e79d3。
答案 2 :(得分:0)
我编写了一个函数来将大十六进制数转换为十进制数 (65)。
CREATE FUNCTION `hexnum_to_decimal`(hex varchar(66)) RETURNS decimal(65,0)
DETERMINISTIC
BEGIN
declare group1 decimal(65);
declare group2 decimal(65);
declare group3 decimal(65);
declare group4 decimal(65);
declare multiplier decimal(65);
if (substr(hex, 1, 2) = "0x") then
set hex = substr(hex, 3); -- trim 0x if exists
end if;
set hex = trim(LEADING '0' from hex);
if (length(hex) > 54) then
return null; -- too big number
end if;
set hex = lpad(hex, 64, 0);
set group1 = cast(conv(substr(hex, 49, 16), 16, 10) as decimal(65));
set group2 = cast(conv(substr(hex, 33, 16), 16, 10) as decimal(65));
set group3 = cast(conv(substr(hex, 17, 16), 16, 10) as decimal(65));
set group4 = cast(conv(substr(hex, 1, 16), 16, 10) as decimal(65));
set multiplier = 18446744073709551616; -- 2 ^ 16
-- check for overflow
if (
(group4 > 15930919) or
(group4 = 15930919 and group3 > 2053574980671369030) or
(group4 = 15930919 and group3 = 2053574980671369030 and group2 > 5636613303479645705) or
(group4 = 15930919 and group3 = 2053574980671369030 and group2 = 5636613303479645705 and group1 > 18446744073709551615)
) then
return null;
end if;
return cast(
group1 +
group2 * multiplier +
group3 * multiplier * multiplier +
group4 * multiplier * multiplier * multiplier
as decimal(65));
END
在你的情况下 000002dcc38af6f209e91518db3e79d3
select hexnum_to_decimal("000002dcc38af6f209e91518db3e79d3");
<块引用>
58055532535286745202684464101843
select hexnum_to_decimal('F316271C7FC3908A8BEF464E3945EF7A253609FFFFFFFFFFFFFFFF');
<块引用>
9999999999999999999999999999999999999999999999999999999999999999
如果传递更大的十六进制数,函数将返回空值。