【问题标题】:Query for matching IP address in SQL Server在 SQL Server 中查询匹配的 IP 地址
【发布时间】:2015-06-26 17:07:59
【问题描述】:

我正在尝试匹配 IP 地址。输入IP地址可以是“5.1.82.1”。

因此,我将输入 IP 地址的第一部分与数据库中以 5 开头的所有 IP 地址进行匹配。我的查询如下

SELECT     top 1   PARSENAME(ipaddress, 4) AS firstpart, ipaddress
FROM            IPs
WHERE        (Country = 'pk') AND (PARSENAME(ipaddress, 4) <= '5')
ORDER BY Expr2 DESC

上面的查询结果是所有以5开头的IP地址。现在我需要将地址的第二部分“1”与数据库中的 IP 地址范围进行匹配。为此,我将再次执行“order by”并选择靠近输入 IP 地址第二部分的顶部记录。

所以我会为第 3 部分和第 4 部分做同样的事情。但问题是我该怎么做?我想我需要使用子查询。但是我将把它放在我的 SQL 语句中。
更新:
样本数据

from              to                  country
[5.1.82.0]       [5.1.82.255]         PK
[5.39.250.0]     [5.39.253.255]       PK
[5.39.255.0]     [5.39.255.255]       PK

重要 在数据库中有 IP 地址范围,例如:5.1.82.0 到 5.1.82.255

【问题讨论】:

  • 显示一些虚拟数据。仅凭描述很难弄清楚
  • 一般IP地址以字符串形式存储在dadatbase中,您可以比较整个IP地址,如ipaddress = "5.1.82.1"。此外,您可以在 ipaddress 上实现索引以获得更快的响应。
  • @KishorPawar 在 db 中有范围但不准确的 IP 地址
  • 如果您将 IP 地址保存在数据库中,以便每个八位字节左填充零到三位数(即“005.001.082.000”),那么您可以简单地使用 BETWEEN 运算符。
  • 更好的方法是将 IP 地址存储为 4 个不同的 tinyint 列。这将提供更小的存储空间和更快的性能(特别是如果 IP 将作为 4 个 tinyint 参数而不是字符串传递给数据库。

标签: sql-server sql-server-2008 tsql sql-server-2012 ip


【解决方案1】:

我在同一件事上使用了以下功能。试试吧,它也应该对你有用。

验证用户的IP地址是否在IP地址范围内。下面的脚本将返回1,如果IP地址在范围内,否则返回0;

CREATE FUNCTION IsIPAddressInRange
(
    @IPAddress varchar(20),
    @StartRange varchar(20),
    @EndRange varchar(20)
)
RETURNS INT
AS
BEGIN
    DECLARE @MAXRANGE BIGINT = 256
    RETURN 
    CASE 
    WHEN PARSENAME(@IPAddress,1) + @MAXRANGE * PARSENAME(@IPAddress,2) + 
    @MAXRANGE * @MAXRANGE * PARSENAME(@IPAddress ,3) + @MAXRANGE * @MAXRANGE * @MAXRANGE * PARSENAME(@IPAddress ,4)
    BETWEEN
    PARSENAME(@StartRange,1) + @MAXRANGE * PARSENAME(@StartRange,2) + 
    @MAXRANGE * @MAXRANGE * PARSENAME(@StartRange ,3) + @MAXRANGE * @MAXRANGE * @MAXRANGE * PARSENAME(@StartRange ,4)
    AND
    PARSENAME(@EndRange,1) + @MAXRANGE * PARSENAME(@EndRange,2) + 
    @MAXRANGE * @MAXRANGE * PARSENAME(@EndRange ,3) + @MAXRANGE * @MAXRANGE * @MAXRANGE * PARSENAME(@EndRange ,4)
    THEN 1
    ELSE 0
    END     
END

我从HERE获取了上述功能。

【讨论】:

  • 如果您希望我将其标记为答案,请稍微解释一下您的代码
  • @FawadAli ...首先我知道它并不完美...正如我所写的那样,我从网上某处获取了它...话虽如此,它实际上只是将所有差异部分相乘ip地址,所以你将有最终数字,可以简单地用于在愤怒之间搜索
  • 它也不是为处理 ip version 6 addesses 而设计的
【解决方案2】:

您可以创建一个函数,使所有 IP 的格式类型为 ###.###.###.###,然后您可以将其用于任何您想要的检查

CREATE FUNCTION dbo.formatIP ( @ip varchar(20) )
RETURNS varchar(20)
AS
BEGIN
    RETURN RIGHT('000'+PARSENAME(@ip,4), 3) + '.' + RIGHT('000'+PARSENAME(@ip,3), 3) + '.' + RIGHT('000'+PARSENAME(@ip,2), 3) + '.' + RIGHT('000'+PARSENAME(@ip,1), 3)
END
GO

现在你可以像这样使用它了:

DECLARE @ip1 varchar(20) = '5.1.82.205', @from varchar(20) = '5.1.82.0', @to varchar(20) = '5.1.82.255'

SELECT 
    CASE 
        WHEN dbo.formatIP(@ip1) BETWEEN dbo.formatIP(@from) AND dbo.formatIP(@to) THEN 1 
        ELSE 0 
    END

【讨论】:

  • 不应该是 Reght('000'+PARSENAME(@ip,...),4) insteat of 3
  • @FawadAli 为什么?,你可以通过SELECT dbo.formatIp('5.1.82.205')查看结果;)。
【解决方案3】:

尝试通过将 ip 地址转换为一个大整数来在下面的范围之间进行搜索,

    declare @ips table ([fromip] varchar(15), [toip] varchar(15), country varchar(5))

        insert into @ips values
        ('5.1.82.0' ,  '5.1.82.255', 'PK'),
        ('5.39.250.0' ,'5.39.253.255','PK'),
        ('5.39.255.0','5.39.255.255','PK')

        declare @ip as varchar(15) ='5.1.82.250'

        SELECT   *
        FROM    @IPs
        WHERE        (Country = 'pk') AND 
        cast(right('00'+PARSENAME(@ip, 4),3)+ right('00'+PARSENAME(@ip, 3),3)+right('00'+PARSENAME(@ip, 2),3) +right('00'+PARSENAME(@ip, 1),3) 
AS bigint) between

        cast(right('00'+PARSENAME(fromip, 4),3)+ right('00'+PARSENAME(fromip, 3),3)+right('00'+PARSENAME(fromip, 2),3) +right('00'+PARSENAME(fromip, 1),3) 
AS bigint) and 
        cast(right('00'+PARSENAME(toip, 4),3)+ right('00'+PARSENAME(toip, 3),3)+right('00'+PARSENAME(toip, 2),3) +right('00'+PARSENAME(toip, 1),3) 
AS bigint)

【讨论】:

    【解决方案4】:
        <?php
        $st = '5.1.82.1';
        echo strstr($st, '.1.82.1',true)
        ?>
    

    【讨论】:

    • @FawadAli 也许你不知道,但我知道。
    • 这个问题是关于 Mysql Server,而不是 PHP。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-03-03
    • 2011-10-05
    • 2012-06-26
    • 2019-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多