IP地址作为文本值存储在Access数据库中,格式为192.168.0.1 - 192.168.0.254在联结表中。
连接表,例如区域
Name IPAddress
Area1 192.168.0.1 - 192.168.0.254
Area2 192.168.1.1 - 192.168.1.254
我需要能够搜索这些范围之间的记录,例如
SELECT * FROM devices WHERE ipaddress = 192.168.0.1 /Returns record Name1
或
SELECT * FROM tablename WHERE ipaddress BETWEEN 192.168.0.1 AND 192.168.0.25 /Returns record Name1,Name2,Name3,etc
答案 0 :(得分:1)
要搜索一系列IP地址,您可以使用像这样的小VBA功能
Option Compare Database
Option Explicit
Public Function ZeroPaddedIP(IP As String) As String
Dim rtn As String, octets() As String, octet As Variant
rtn = ""
octets = Split(IP, ".")
For Each octet In octets
rtn = rtn & "." & Format(Val(octet), "000")
Next
ZeroPaddedIP = Mid(rtn, 2) ' trim leading "."
End Function
它用前导零填充八位字节,所以
ZeroPaddedIP("192.168.0.1") --> "192.168.000.001"
您的查询可以执行类似
的操作SELECT * FROM tablename
WHERE ZeroPaddedIP(ipaddress) BETWEEN "192.168.000.001" AND "192.168.000.025"
该查询将执行表扫描,因为它无法使用[ipaddress]上的任何现有索引。如果性能有问题,您可以考虑以填充形式存储您的IP地址(代替正常的非填充格式,或者除了正常的非填充格式之外)。
修改强>
对于名为[NetworkData]的测试表...
ID IP Description
-- ------------- -----------
1 192.168.0.1 router
2 192.168.0.2 test server
3 192.168.0.3 dev server
4 192.168.0.102 test client
5 192.168.0.103 dev client
...上面显示的VBA函数可以在这样的Access查询中使用...
SELECT
IP,
ZeroPaddedIP(IP) AS PaddedIP
FROM NetworkData
......产生以下结果......
IP PaddedIP
------------- ---------------
192.168.0.1 192.168.000.001
192.168.0.2 192.168.000.002
192.168.0.3 192.168.000.003
192.168.0.102 192.168.000.102
192.168.0.103 192.168.000.103
...但仅限于从Access本身执行查询。可以从以下查询获得相同的结果,但是如果从其他应用程序(如Excel)对Access数据库运行查询,则此结果将起作用:
SELECT
IP,
Right('000' & Octet1, 3) & '.' & Right('000' & Octet2, 3) & '.' & Right('000' & Octet3, 3) & '.' & Right('000' & Octet4, 3) AS PaddedIP
FROM
(
SELECT
IP,
Octet1,
Octet2,
Left(TheRest2, InStr(TheRest2, '.') - 1) AS Octet3,
Mid(TheRest2, InStr(TheRest2, '.') + 1) AS Octet4
FROM
(
SELECT
IP,
Octet1,
Left(TheRest1, InStr(TheRest1, '.') - 1) AS Octet2,
Mid(TheRest1, InStr(TheRest1, '.') + 1) AS theRest2
FROM
(
SELECT
IP,
Left(IP, InStr(IP, '.') - 1) AS Octet1,
Mid(IP, InStr(IP, '.') + 1) AS theRest1
FROM NetworkData
) AS q1
) AS q2
) AS q3
因此,如果您从Excel(或任何地方)查询数据并尝试使用
SELECT * FROM NetworkData
WHERE IP Between '192.168.0.1' And '192.168.0.25'
你会得到以下不正确的结果
ID IP Description
-- ------------- -----------
1 192.168.0.1 router
2 192.168.0.2 test server
4 192.168.0.102 test client
5 192.168.0.103 dev client
而如果您使用
SELECT NetworkData.*
FROM
NetworkData
INNER JOIN
(
SELECT
IP,
Right('000' & Octet1, 3) & '.' & Right('000' & Octet2, 3) & '.' & Right('000' & Octet3, 3) & '.' & Right('000' & Octet4, 3) AS PaddedIP
FROM
(
SELECT
IP,
Octet1,
Octet2,
Left(TheRest2, InStr(TheRest2, '.') - 1) AS Octet3,
Mid(TheRest2, InStr(TheRest2, '.') + 1) AS Octet4
FROM
(
SELECT
IP,
Octet1,
Left(TheRest1, InStr(TheRest1, '.') - 1) AS Octet2,
Mid(TheRest1, InStr(TheRest1, '.') + 1) AS theRest2
FROM
(
SELECT
IP,
Left(IP, InStr(IP, '.') - 1) AS Octet1,
Mid(IP, InStr(IP, '.') + 1) AS theRest1
FROM NetworkData
) AS q1
) AS q2
) AS q3
) AS q4
ON q4.IP = NetworkData.IP
WHERE q4.PaddedIP Between '192.168.000.001' And '192.168.000.025'
您将收到以下正确结果
ID IP Description
-- ----------- -----------
1 192.168.0.1 router
2 192.168.0.2 test server
3 192.168.0.3 dev server
答案 1 :(得分:1)
成功的方法将由三部分组成:
解析IPAddress
列并将其拆分为两个逻辑(文本)列:IPAddressLow
和IPAddressHigh
,用于捕获区域的IP范围。我们称之为qryAreas
:
select
[Name]
, ... as IPAddressLow
, ... as IPAddressHigh
from Areas
实现一个函数(在VBA中,然后可以从Access SQL中调用)来对IP地址进行比较。比较器功能可能类似于:
' Returns:
' -1 if IP1 < IP2
' 0 if IP1 = IP2
' 1 if IP1 > IP2
Function CompareIPAddresses(ip1 As String, ip2 As String) As Integer
ip1_arr = Split(ip1, ".")
ip2_arr = Split(ip2, ".")
For i = 0 To 3
ip1_arr(i) = CLng(ip1_arr(i))
ip2_arr(i) = CLng(ip2_arr(i))
Next i
If ip1 = ip2 Then
retval = 0
ElseIf ip1_arr(0) < ip2_arr(0) Then
retval = -1
ElseIf ip1_arr(0) = ip2_arr(0) And ip1_arr(1) < ip2_arr(1) Then
retval = -1
ElseIf ip1_arr(0) = ip2_arr(0) And ip1_arr(1) = ip2_arr(1) And ip1_arr(2) < ip2_arr(2) Then
retval = -1
ElseIf ip1_arr(0) = ip2_arr(0) And ip1_arr(1) = ip2_arr(1) And ip1_arr(2) = ip2_arr(2) And ip1_arr(3) < ip2_arr(3) Then
retval = -1
Else
retval = 1
End If
CompareIPAddresses = retval
End Function
在查询中使用上述函数来确定IP地址是否等于某个值或是否在某个范围内。例如,如果您有一个地址192.168.1.100
并想知道它在哪个区域,您可以这样做:
select [Name]
from qryAreas
where CompareIPAddresses(IPAddressLow, '192.168.1.100') in (-1, 0)
and CompareIPAddresses('192.168.1.100', IPAddressHigh) in (-1, 0)
这里的where
子句是更优雅的where 192.168.1.100 between IPAddressLow and IPAddressHigh
语法的笨重等价物,因为你没有本机IP地址数据类型及其相应的运算符 - 所以你滚动你的自己的。