将IP地址范围导入DB表 - 如何在T-SQL中检查范围冲突?

时间:2014-08-07 22:45:28

标签: sql sql-server tsql ip-address

我在SQL Server数据库中有一个表,用于存储起始和结束NUMERIC IP地址值(不是IPv4)。我将在此表中导入其他IP地址范围。在实际导入之前,是否有人知道如何检查,如果要导入的任何范围与任何现有范围冲突,使用T-SQL?谢谢。

2 个答案:

答案 0 :(得分:1)

给出类似

的表格
 create table IPRanges (
      IPStart int not null unique nonclustered
     ,IPEnd   int not null unique nonclustered
     --other fields
  )

然后这里的函数将执行所需的测试。如果需要,可以在选择中添加TOP 1

create function dbo.ConflictingRanges(@IPStart int, @IPEnd int)
returns table return(
    select IPStart, IPEnd
    from dbo.IPRanges
    where IPStart <= @IPEnd
      and IPEnd   >= @IPStart
)

以下测试用例

insert dbo.IPRanges(IPStart,IPEnd)
values (2,4)
      ,(8,10)
      ,(15,20)
;

with trials as (
    select * from (values
         ( 0, 1)
        ,( 3, 5)
        ,( 9, 9)
        ,(19,21)
        ,(25,30)
        ,( 1,35)
    )trials(IPStart,IPEnd)
)
select 
     trials.IPStart
    ,trials.IPEnd
    ,data.IPStart as conflictStart
    ,data.IPEnd   as ConflictEnd
from trials
outer apply dbo.ConflictingRanges(trials.IPStart,trials.IPEnd) data;

的产率:

IPStart     IPEnd       conflictStart ConflictEnd
----------- ----------- ------------- -----------
0           1           NULL          NULL
3           5           2             4
9           9           8             10
19          21          15            20
25          30          NULL          NULL
1           35          2             4
1           35          8             10
1           35          15            20

如果需要,可以通过返回count(*)而不是实际的冲突值来转换为布尔结果。

答案 1 :(得分:1)

以下过程显示了如何转换IP地址。一旦将IP移植到数字上,就可以轻松地检查现有范围。如果您需要进一步说明,请参阅Here

DECLARE @StrIPOctet VARCHAR(15) = '192.168.10.255'
DECLARE @StrIPlong FLOAT = '3232238081'
DECLARE @Octet1 BIGINT
DECLARE @Octet2 TINYINT
DECLARE @Octet3 TINYINT
DECLARE @Octet4 TINYINT
DECLARE @OctetPart BIGINT

SELECT CONVERT(BIGINT, PARSENAME(@StrIPOctet, 1)) 
    + CONVERT(BIGINT, PARSENAME(@StrIPOctet, 2)) * 256 
    + CONVERT(BIGINT, PARSENAME(@StrIPOctet, 3)) * 65536 
    + CONVERT(BIGINT, PARSENAME(@StrIPOctet, 4)) * 16777216

SET @Octet1 = @StrIPlong / 16777216
SET @OctetPart = @StrIPlong - @Octet1 * 16777216
SET @Octet2 = @OctetPart / 65536
SET @OctetPart = @OctetPart - @Octet2 * 65536
SET @Octet3 = @OctetPart / 256
SET @Octet4 = @OctetPart - @Octet3 * 256

SELECT CONVERT(VARCHAR, @Octet1) + '.' 
    + CONVERT(VARCHAR, @Octet2) + '.' 
    + CONVERT(VARCHAR, @Octet3) + '.' 
    + CONVERT(VARCHAR, @Octet4)