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