2012-05-04 42 views
2

IP地址通过以下任何方式存储在我的表中。如何根据表中的IP地址列表验证用户的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地址验证记录对这个表?

回答

1

您可以在每个位置(点之间)用'#'替换访客IP的号码,并执行常规的WHERE子句。因此,您会得到一个包含五个比较(其中一个用于直接匹配,四个用每个位置上的替换#)的where子句的语句。

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

+3

运气好的时候,我们向IPv6迁移,哈哈。 – Styxxy

+0

此外,我怀疑这个例子是过于简化,它会需要超过五个比较。也许...... heh –

+0

应该是15,假设你不需要匹配#。#。#。# –

4

尝试使用LIKE运营商,像这样:

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

但是,如果你在你的表有很多记录(它不能使用任何索引),这种方法是非常有问题的表现,明智的。

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

  • 在四个数字列
  • 使用null来表示一个通配符(例如拆分IP,你的最后一个规则将成为192, null, 34, 12
  • 在客户机上,在对应的4份分割IP和使用条件,例如:

    WHERE ([email protected] OR IP1 is null) AND ([email protected] OR IP2 is null) AND ...

这样我想你可以在四列上使用索引来加快速度,如果需要的话。

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