2012-05-04 123 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