SQL Server2014。
TL DR 我需要能够在VARBINARY(16)字段上的IP范围之间进行查询,但是第一次运行时得到的结果不正确,而当我运行时却得到了正确的结果再次重新运行查询。为什么会这样?
我正在尝试获取IPGeoLocation数据,数据供应商在其中按IP范围(IPv4和IPv6)提供纬度和经度。原始IP地址范围(即开始和结束)存储为VARCHAR(39),十六进制转换存储为VARBINARY(16),使用CONVERT(VARBINARY(16),IpStart)作为对表的更新来完成。这意味着总共有四列。我要审核两个数据供应商,以查看实际结果,因此有两个包含IPGeolocation数据的表。此外,每个表上都有两个非群集列,分别覆盖VARCHAR(39)列和VARBINARY(16)列。
当我查询VARCHAR(39)和VARBINARY(16)之间的地址范围时,我从数据供应商之一的SQL Server收到不一致的响应。现在,这是一个关键,我正在使用CONVERT(VARBINARY(16),IpStart)快速将VARCHAR(39)转换为VARBINARY(16)。我的期望是两个查询返回相同的结果。但是,第一次运行时结果在十六进制列之间的查询不正确的地方是不同的。但是,当我重新运行查询时,十六进制列输出匹配。为什么?这是SQL Server中的缓存问题吗?这可能是错误吗?有人遇到过这个问题吗?
DECLARE @RowKey INT
,@Ip VARCHAR(39) = '2600:1011:b152:d4aa:b158:af57:d0d8:ef6d'
DECLARE @IpHex VARBINARY(16) = CONVERT(VARBINARY(16), @Ip)
,@RowKeyHex INT
SELECT @RowKey = RowKey
FROM IpGeoLocation
WHERE ProtocolKey = 7 -- 'IPV4' = 6 & 'IPV6' = 7
AND CONVERT(VARBINARY(16), @Ip) BETWEEN CONVERT(VARBINARY(16), NetworkStartIp) AND CONVERT(VARBINARY(16), NetworkEndIp)
SELECT @RowKeyHex = RowKey
FROM IpGeoLocation
WHERE ProtocolKey = 7 -- 'IPV4' = 6 & 'IPV6' = 7
AND @IpHex BETWEEN NetworkStartIphex AND NetworkEndIphex
SELECT @Ip, @IpHex
,RowKey, ProtocolKey, ProtocolId, Latitude, Longitude, NetworkStartIp, NetworkEndIp, NetworkStartIpHex, NetworkEndIpHex
FROM IpGeoLocation
WHERE RowKey = @RowKey
SELECT @Ip, @IpHex
,RowKey, ProtocolKey, ProtocolId, Latitude, Longitude, NetworkStartIp, NetworkEndIp, NetworkStartIpHex, NetworkEndIpHex
FROM IpGeoLocation
WHERE RowKey = @RowKeyHex
结果: