PostgreSQL IP地址:通过inet数据搜索正确的结果?
问题描述:
当询问给定的IP地址(inet
类型)是否在数据库中搜索正确的结果时,我在PostgreSQL上遇到问题。我将一步一步提供我正在做的事情。PostgreSQL IP地址:通过inet数据搜索正确的结果?
CREATE TABLE public.test (
ip inet,
a character varying
);
INSERT INTO public.test (ip, a) VALUES
('1111:0000:0101:000A:0002:0003:0004:0005', 'admin1'),
('1111:0001:0101:000A:0002:0003:0004:0005', 'admin2'),
('1111:0011:0101:000A:0002:0003:0004:0005', 'admin3'),
('1111:0111:0101:000A:0002:0003:0004:0005', 'admin4'),
('1111:1111:0101:000A:0002:0003:0004:0005', 'admin5');
然后我想通过'1111:0'
搜索ip
,应该找的结果
1111:0000:0101:000A:0002:0003:0004:0005
1111:0001:0101:000A:0002:0003:0004:0005
1111:0011:0101:000A:0002:0003:0004:0005
1111:0111:0101:000A:0002:0003:0004:0005
答
如果你要搜索的inet
地址一些文本表示(与f.ex. LIKE
),你”会很难过;因为inet
输出是标准化的。 F.ex:
input | output
1111:0000:0000:0000:0000:0000:0000:0005 | 1111::5/128
1111:0001:0101:000A:0002:0003:0004:0005 | 1111:1:101:a:2:3:4:5/128
因此,前导零都不见了&,只有零的最大块与::
取代(这是完全有效的在IPv6中)。
但是,如果你想找到inet
addresses,其中有20 领先位像1111:0
,你可以使用subnets。
为1111:0
,你真正需要的孩子(网络/)的1111::/20
(与contains operator: >>
)主机:
select addr,
inet '1111::/20' >> addr "is within '1111::/20'"
from (values (inet '1111:0000:0000:0000:0000:0000:0000:0005'),
(inet '1111:0001:0101:000A:0002:0003:0004:0005'),
(inet '1111:0011:0101:000A:0002:0003:0004:0005'),
(inet '1111:0111:0101:000A:0002:0003:0004:0005'),
(inet '1111:1111:0101:000A:0002:0003:0004:0005'),
(inet '1111:F111:0101:0000:0000:0000:0000:0005')) v(addr)
会产生:
addr | is within '1111::/20'
1111::5/128 | t
1111:1:101:a:2:3:4:5/128 | t
1111:11:101:a:2:3:4:5/128 | t
1111:111:101:a:2:3:4:5/128 | t
1111:1111:101:a:2:3:4:5/128 | f
1111:f111:101::5/128 | f
答
select * from test where
cast((ip)as varchar) like '%a000::%'
or cast((ip)as varchar) like '%a000:_:%'
or cast((ip)as varchar) like '%a000:__:%'
or cast((ip)as varchar) like '%a000:___:%
or cast((ip)as varchar) like '%a000:_____'
or cast((ip)as varchar) like '%a000:______'
or cast((ip)as varchar) like '%a000:_______'
+0
但是,这如何帮助在f.ex中搜索'1111:0'。 '1111:1:101:A:2:3:4:5'?这只会在您只搜索一个区块时起作用。如果那样的话,你也可以使用一个'LIKE'。 – pozs
就像你说的那样,我们可以搜索正确的ip字符串(1111:0)。如果ip在中间或末尾匹配,这种方式不能解决这个问题。 – ggg
@ggg是的,你不能在'inet'内搜索,因为它的输出是标准化的。您可以(理论上)在经过标准化的表格内进行搜索,但这不会相同(请参阅链接的rextester示例)。 – pozs
我找到一种方法,我们不仅可以搜索作为字符串头部的ip,还可以搜索字符串'1111:0'位于中间还是结尾。 – ggg