当询问给定的IP地址(inet
类型)是否在数据库中搜索正确的结果时,我在PostgreSQL上遇到了问题。我将逐步提供我正在做的事情。
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');
然后我希望ip
搜索'1111:0'
,它应该找到结果
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
答案 0 :(得分:2)
如果您想搜索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
所以,领先的零已经消失了。并且只有{0}的最大块被::
替换(在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
答案 1 :(得分:0)
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:_______'