选择两个IP范围之间的记录

alw*_*NET 14 sql sql-server

我有一个存储表ID,Name,Code,IPLow,IPHigh如:

1, Lucas, 804645, 192.130.1.1, 192.130.1.254
2, Maria, 222255, 192.168.2.1, 192.168.2.254
3, Julia, 123456, 192.150.3.1, 192.150.3.254
Run Code Online (Sandbox Code Playgroud)

现在,如果我有一个IP地址192.168.2.50,我该如何检索匹配的记录?

编辑

根据Gordon的回答(我得到了编译错误),这就是我所拥有的:

select PersonnelPC.*
from (select PersonnelPC.*,
             (
              cast(parsename(iplow, 4)*1000000000 as decimal(12, 0)) +
              cast(parsename(iplow, 3)*1000000 as decimal(12, 0)) +
              cast(parsename(iplow, 2)*1000 as decimal(12, 0)) +
              (parsename(iplow, 1))
             ) as iplow_decimal,
            (
              cast(parsename(iphigh, 4)*1000000000 as decimal(12, 0)) +
              cast(parsename(iphigh, 3)*1000000 as decimal(12, 0)) +
              cast(parsename(iphigh, 2)*1000 as decimal(12, 0)) +
              (parsename(iphigh, 1))
             ) as iphigh_decimal
      from PersonnelPC
     ) PersonnelPC
where 192168002050 between iplow_decimal and iphigh_decimal;
Run Code Online (Sandbox Code Playgroud)

但这给了我一个错误:

Msg 8115, Level 16, State 2, Line 1
Arithmetic overflow error converting expression to data type int.
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Gor*_*off 7

痛苦.SQL Server具有糟糕的字符串操作功能.但它确实提供了parsename().此方法将IP地址转换为较大的十进制值以进行比较:

select t.*
from (select t.*,
             (cast(parsename(iplow, 4)*1000000000.0 as decimal(12, 0)) +
              cast(parsename(iplow, 3)*1000000.0 as decimal(12, 0)) +
              cast(parsename(iplow, 2)*1000.0 as decimal(12, 0)) +
              cast(parsename(iplow, 1) as decimal(12, 0))
             ) as iplow_decimal,
             (cast(parsename(iphigh, 4)*1000000000.0 as decimal(12, 0)) +
              cast(parsename(iphigh, 3)*1000000.0 as decimal(12, 0)) +
              cast(parsename(iphigh, 2)*1000.0 as decimal(12, 0)) +
              cast(parsename(iphigh, 1) as decimal(12, 0))
             ) as iphigh_decimal
      from t
     ) t
where 192168002050 between iplow_decimal and iphigh_decimal;
Run Code Online (Sandbox Code Playgroud)

我应该注意,IP地址通常作为4字节无符号整数存储在数据库中.这使得比较更容易...虽然您需要复杂的逻辑(通常包含在函数中)以将值转换为可读格式.

  • 有趣地使用基数10转换使其可读(我使用4x4字节长度来存储IP).强制转换会使速度变慢 - 考虑将IP存储为非人类可读的,或者添加触发器以更新存储与人类可读IP地址匹配的长值的第二个字段. (2认同)

Jay*_*hav 5

尝试这种简单的检查范围

DECLARE @IP NVARCHAR(30)='192.168.500.1'

SELECT  * FROM 
Branches
WHERE
CAST (PARSENAME(@IP,4) AS INT)>=CAST(PARSENAME(IPLow,4) AS INT) AND CAST(PARSENAME(@IP,3) AS INT)>=CAST(PARSENAME(IPLow,3) AS INT) AND CAST(PARSENAME(@IP,2) AS INT)>=CAST(PARSENAME(IPLow,2) AS INT) AND CAST(PARSENAME(@IP,1) AS INT)>=CAST(PARSENAME(IPLow,1) AS INT)
AND
CAST(PARSENAME( @IP,4) AS INT) <= CAST(PARSENAME(IPHigh ,4) AS INT) AND CAST(PARSENAME(@IP ,3) AS INT) <=CAST(PARSENAME(IPHigh ,3) AS INT) AND CAST(PARSENAME(@IP ,2) AS INT) <=CAST(PARSENAME(IPHigh ,2) AS INT) AND CAST(PARSENAME(@IP ,1) AS INT)<=CAST(PARSENAME(IPHigh ,1) AS INT)
Run Code Online (Sandbox Code Playgroud)

根据@Ed Haper评论演员需要.