【问题标题】:Finding gaps in a table of IP address blocks在 IP 地址块表中查找间隙
【发布时间】:2014-11-20 19:19:26
【问题描述】:

我在 SQL Server 2005 中有一个包含以下字段和示例数据的表: id block block_start block_end size 523 10.211.15.16/28 0x0AD30F10 0x0AD30F1F 16 531 10.211.15.36/30 0x0AD30F24 0x0AD30F27 4 532 10.211.15.40/29 0x0AD30F28 0x0AD30F2F 8 533 10.211.15.48/29 0x0AD30F30 0x0AD30F37 8 525 10.211.15.72/29 0x0AD30F48 0x0AD30F4F 8

id 是一个 INT 标识列。 block 是 VARCHAR(18),表示 CIDR 格式的 IP 块。 block_start 和 block_end 是 BINARY(4),分别代表块中的第一个和最后一个 IPv4 地址。大小是块中 IP 地址的数量。

以给定的 IP 范围和 IP 数量作为输入,我需要一种方法来查询第一个可用间隙。例如,我可能想找到 10.211.15.1610.211.15.80 之间的 4 个 IP 地址的第一个缺失间隔。在本例中,正确的输出应该是 10.211.15.32/30(0x0AD30F20 到 0x0AD30F23)。如果我希望 8 IP 地址的第一个间隙在同一范围内,正确的输出应该是 10.211.15.56/29(0x0AD30F38 到 0x0AD30F3F)。

CIDR (varchar) 或二进制格式的输出不是问题,因为我有可以在两者之间轻松转换的函数,但我想需要对二进制字段进行查询。

如有必要,我可以利用应用程序逻辑(Java 或 ColdFusion),但如果我能提供帮助,我宁愿不这样做。

添加了 sqlfiddle:http://sqlfiddle.com/#!3/d45ad

【问题讨论】:

标签: sql sql-server tsql sql-server-2005


【解决方案1】:

您可以通过使用lead() 并将块字段转换为整数来找到间隙。像这样的:

select t.*
from (select t.*,
             cast(lead(block_start) over (order by block_start) as bigint) as nextstart,
             cast(block_end as bigint) as thisend
      from iptable t
     ) t
where nextstart - thisend - 1 > @MYNUMBEROFIPS;

如果您想在块上使用范围比较,请非常小心。在进行比较之前,您应该将块转换为数值。

编辑:

您可以通过以下方式获得等效功能:

select t.*
from (select t.*, cast(block_end as bigint) as thisend,
             (select top 1 cast(block_start as bigint)
              from iptable t2
              where t2.block_start > t.block_start
              order by t2.block_start
             ) as nextstart
      from iptable t
     ) t
where nextstart - thisend - 1 > @MYNUMBEROFIPS;

【讨论】:

  • 我没有提到这是 SQL Server 2005 并且在该版本中没有 Lead()。此外,由于八位字节的整数范围是 0-255,转换为整数不会导致八位字节边缘出现问题吗?
  • 谢谢你,@gordon-linoff。你的编辑几乎让我一路走来。我必须做一些小的调整:1)最后的 WHERE 子句应该是>=,以确保它得到与 IP 数量完全匹配的间隙 2)要找到子集中的间隙,我必须向 t2 子查询添加条件像这样缩小块:where t2.block_start > t.block_start and t.block_start > @MYBLOCKSTART and t.block_end < @MYBLOCKEND
猜你喜欢
  • 2016-10-25
  • 1970-01-01
  • 2016-05-05
  • 1970-01-01
  • 2013-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多