我使用以下命令将IP地址存储在数据库中:
cast(INET6_ATON(trim(:ipbinary)) as binary(16)))
我的专栏是:
varbinary(16)
我试过使用mysql函数
INET6_NTOA
将其转换回IPv4格式,但是还没有运气。我需要的IP是:
66.249.64.90
DB值是:
42f9405a000000000000000000000000
INET6_NTOA
给我:42f9:405a::
INET6_NTOA(UNHEX(
给了我一个NULL
响应。我使用PHP作为脚本语言,因此如果那里也有功能,我也可以使用它。这是我的完整查询:
SELECT delete_ip, INET6_NTOA(ip_binary), ip_binary FROM `stats`
这是响应:
谢谢。
(我不能只使用
delete_ip
,因为顾名思义,该列将被删除。) 最佳答案
它没有转换回IPv4可读格式,而是转换为IPv6,因为INET6_NTOA
(二进制值)的参数为16个字节。
该功能将其视为IPv6地址的表示,而不是仅四个字节的IPv4地址。
我认为问题可以追溯到问题的第一行SQL,即强制转换为BINARY(16)
。这将返回16字节的固定长度。从为IPv4地址返回的四个字节开始,然后在右边用零填充,直到16个字节的长度。
如果我们删除固定长度的转换,并允许INET6_ATON
函数的结果仅为四个字节,会发生什么?
当数据库中存储的值只有四个字节时会发生什么?
如果我们更正了stats
表的内容,将那个16字节的二进制值(IPv6地址的表示形式)更改为一个IPv4地址的四字节的二进制表示形式,该怎么办?
UPDATE `stats`
SET ip_binary = INET6_ATON('66.249.64.90')
WHERE ip_binary = CAST(INET6_ATON('66.249.64.90') AS BINARY(16))
- 或者 -
UPDATE `stats`
SET ip_binary = X'42f9405a' + 0
WHERE ip_binary = X'42f9405a000000000000000000000000' + 0
后续行动
问题说...“使用[表达式]在数据库[列]中存储IP地址,如下所示:
cast(INET6_ATON(trim(:ipbinary)) as binary(16)))
我们不需要使用
CAST
。而且我们不需要使用CONVERT
,HEX
/UNHEX
或SUBSTR
。使用相同的表达式转换IPv4和IPv6地址: INSERT ... ip_binary ... VALUES ( ... , INET6_ATON( :ip_string ) , ...
并将它们转换回这样的字符串:
SELECT ... , INET6_NTOA( ip_binary ) AS ip_string , ...
带有
CAST
,CONVERT
,SUBSTR
,HEX
/UNHEX
的rigmarole令人困惑,并导致事情不起作用。为了更正已经存储在数据库中的值,我们需要一种方法来区分16个字节的二进制表示形式中的哪一个实际上是应该存储为4个字节的IPv4地址。
如果
ip_delete
包含字符串表示形式,我们可以重新转换为二进制表示形式。 UPDATE `stats`
SET ip_binary = INET6_ATON( ip_delete )
示范
CREATE TABLE `addr` (ip_string VARCHAR(45), ip_binary VARBINARY(16)) ;
INSERT INTO `addr` VALUES ( '66.249.64.90' , INET6_ATON( '66.249.64.90' ));
INSERT INTO `addr` VALUES ( '127.0.0.1' , INET6_ATON( '127.0.0.1' ));
INSERT INTO `addr` VALUES ( '192.168.1.1' , INET6_ATON( '192.168.0.1' ));
INSERT INTO `addr` VALUES ( '2001:4860:4860::8888' , INET6_ATON( '2001:4860:4860::8888' ));
SELECT ip_string, HEX(ip_binary), INET6_NTOA(ip_binary) FROM `addr` ;
ip_string HEX(ip_binary) INET6_NTOA(ip_binary)
-------------------- -------------------------------- -----------------------
66.249.64.90 42F9405A 66.249.64.90
127.0.0.1 7F000001 127.0.0.1
192.168.1.1 C0A80001 192.168.0.1
2001:4860:4860::8888 20014860486000000000000000008888 2001:4860:4860::8888