获取或计算 T-SQL 上的下一个 IP 地址

Getting or calculating next IP Address on T-SQL

我有一个 table 来获取 IP 地址列表。我想 get/calculate IP 地址提供每个 IP 的最后一个(或任何)子网的 +2 数值。 我该怎么做?

例如;

SELECT * FROM tblDevices

图片:IP list

就这样;

10.0.128.14 -> 10.0.128.16

10.0.128.140 -> 10.0.128.142

10.0.128.141 -> 10.0.128.143

10.0.128.142 -> 10.0.128.144

尝试 PARSENAME:

SELECT PARSENAME(IP_Address, 4) + '.' +
    PARSENAME(IP_Address, 3) + '.' +
    PARSENAME(IP_Address, 2) + '.' +
    CONVERT(VARCHAR(5), PARSENAME(IP_Address, 1) + 2)
FROM tblDevices

当你想处理“255 问题”时,你可以使用我刚刚编写的解决方案 CURSOR:

DECLARE @IP_Address VARCHAR(30)
DECLARE MY_CURSOR CURSOR LOCAL READ_ONLY FAST_FORWARD
FOR
SELECT IP_Address
FROM tblDevices
OPEN MY_CURSOR
FETCH NEXT FROM MY_CURSOR INTO @IP_Address
WHILE @@FETCH_STATUS = 0
BEGIN
    IF(CAST(PARSENAME(@IP_Address, 1) AS INT) IN (254, 255))
    BEGIN
        IF(CAST(PARSENAME(@IP_Address, 2) AS INT) = 255)
        BEGIN
            IF(CAST(PARSENAME(@IP_Address, 3) AS INT) = 255)
            BEGIN
                IF(CAST(PARSENAME(@IP_Address, 4) AS INT) = 255)
                BEGIN
                    SELECT '255.255.255.255'
                END
                ELSE
                    SELECT
                        CASE WHEN CAST(PARSENAME(@IP_Address, 1) AS INT) = 254 THEN (CAST(PARSENAME(@IP_Address, 4) AS INT) + 1) + '.0.0.1'
                        ELSE (CAST(PARSENAME(@IP_Address, 4) AS INT) + 1) + '.0.0.2' END
            END
            ELSE
                SELECT
                    CASE WHEN CAST(PARSENAME(@IP_Address, 1)AS INT) = 254 THEN PARSENAME(@IP_Address, 4) + '.' + CONVERT(VARCHAR(5), (PARSENAME(@IP_Address, 3)) + 1) + '.0.1'
                    ELSE PARSENAME(@IP_Address, 4) + '.' + CONVERT(VARCHAR(5), (PARSENAME(@IP_Address, 3)) + 1) + '.0.2' END
        END
        ELSE
            SELECT
                CASE WHEN CAST(PARSENAME(@IP_Address, 1) AS INT) = 254 THEN PARSENAME(@IP_Address, 4) + '.' + PARSENAME(@IP_Address, 3) + '.' + CONVERT(VARCHAR(5), (PARSENAME(@IP_Address, 2) + 1)) + '.1'
                ELSE PARSENAME(@IP_Address, 4) + '.' + PARSENAME(@IP_Address, 3) + '.' + CONVERT(VARCHAR(5), (PARSENAME(@IP_Address, 2)) + 1) + '.2' END
    END
    ELSE
        SELECT PARSENAME(@IP_Address, 4) + '.' + PARSENAME(@IP_Address, 3) + '.' + PARSENAME(@IP_Address, 2) + '.' + CONVERT(VARCHAR(5), (PARSENAME(@IP_Address, 1) + 2))

    FETCH NEXT FROM MY_CURSOR INTO @IP_Address
END

有点难看,但还行。

这使用基于数字的作品 table...

declare @string varchar(20)
set @string='.10.0.128.14.'

;with cte
as
(
select 
substring(@string,n+1,charindex('.',@string,n+1)-n-1) as b,row_number() over (order by (select 1)) as rn
from numbers
where 
substring(@string,n,1)='.'
and n<len(@string)
)
select 
distinct stuff((select '.'+case when rn =(select max(rn) from cte) then convert(varchar(10),b+2) else convert(varchar(10),b) end
from cte for xml path('')),1,1,'') b
 from cte

output:10.0.128.16

根据评论更新:

declare @string varchar(20)
set @string='.192.168.1.255.'

;with cte
as
(

select 
substring(@string,n+1,charindex('.',@string,n+1)-n-1) as b,row_number() over (order by (select 1)) as rn
from numbers
where 
substring(@string,n,1)='.'
and n<len(@string)
)
select
 stuff((select '.'+
case 
when rn =(select max(rn) from cte)  and b=255
then convert(varchar(10),1) 

----
when rn=(select max(rn)-1 from cte)  and ((select b from cte where rn=(select max(rn) from cte))=255)
then convert(varchar(10),b+1)

when rn =(select max(rn) from cte)  
then convert(varchar(10),b+2) else convert(varchar(10),b) 
end
from cte for xml path('')),1,1,'') b,rn,b
 from cte
 where rn=1

output:192.168.2.1