如何根据表中的IP地址列表验证用户的IP地址?

时间:2012-05-04 14:57:39

标签: sql sql-server tsql stored-procedures

IP地址以下列任何方式存储在我的表格中。

192.12.34.12
192.12.#.12
192.#.34.12

现在,在我的应用程序中,我想通过使用.net代码捕获登录用户的IP地址来自动验证此表的用户IP地址。

现在,如果用户IP是

192.12.34.12
192.12.45.12

192.56.34.12-- it should be valid.
191.12.34.12-- Invalid

如何创建一个SQL查询或存储过程,它将根据此表验证登录用户的IP地址?

3 个答案:

答案 0 :(得分:4)

尝试使用LIKE运算符,如下所示:

SELECT *
FROM IPRecords
WHERE @UsersIp like replace(IP, '#', '%')

但是,如果您的表中有很多记录(它不能使用任何索引),这种方法在性能方面可能非常有问题。

如果表现真的是一个问题,另一种方法可能是:

  • 将IP划分为四个数字列
  • 使用null表示通配符(例如,您的上一条规则将成为192, null, 34, 12
  • 在客户端上,将IP拆分为相应的4个部分,并使用如下条件:

    WHERE (IP1=@IP1 OR IP1 is null) AND (IP2=@IP2 OR IP2 is null) AND ...

这样我认为你可以使用四列上的索引来加快速度。

答案 1 :(得分:3)

您可以使用PARSENAME函数将IP地址值拆分为四个部分并单独进行比较。

创建并填充测试数据脚本

CREATE TABLE ipaddresses
( 
    ip VARCHAR(20) NOT NULL
);

INSERT INTO ipaddresses (ip) VALUES
    ('192.12.34.12'),
    ('192.12.#.12'),
    ('192.#.34.12');

场景#1

DECLARE @userip VARCHAR(20)
SET     @userip = '192.56.34.12'

;WITH ips AS
(
    SELECT  REPLACE(ip, '#', '%') AS ip
    FROM    ipaddresses
)
SELECT  COUNT(ip) AS validcount
FROM    ips
WHERE   PARSENAME(@userip, 1) LIKE PARSENAME(ip, 1)
AND     PARSENAME(@userip, 2) LIKE PARSENAME(ip, 2)
AND     PARSENAME(@userip, 3) LIKE PARSENAME(ip, 3)
AND     PARSENAME(@userip, 4) LIKE PARSENAME(ip, 4);

VALIDCOUNT
----------
    1

场景#2

DECLARE @userip VARCHAR(20)
SET     @userip = '191.12.34.12'

;WITH ips AS
(
    SELECT  REPLACE(ip, '#', '%') AS ip
    FROM    ipaddresses
)
SELECT  COUNT(ip) AS validcount
FROM    ips
WHERE   PARSENAME(@userip, 1) LIKE PARSENAME(ip, 1)
AND     PARSENAME(@userip, 2) LIKE PARSENAME(ip, 2)
AND     PARSENAME(@userip, 3) LIKE PARSENAME(ip, 3)
AND     PARSENAME(@userip, 4) LIKE PARSENAME(ip, 4);

VALIDCOUNT
----------
   0

答案 2 :(得分:1)

你可以做一个声明,你在每个位置(点之间)用'#'替换访客IP的号码,并做一个常规的WHERE子句。所以你得到一个带有包含五个比较的where子句的语句(一个用于直接匹配,四个用于每个位置的替换#)。

您可以使用CHARINDEX查找点,并使用SUBSTRING构建比较变量。