获取或计算 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
我有一个 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