2017-03-16 8 views
1

주어진 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'); 

난 당신이 (f.ex. LIKE와) inet 주소의 텍스트 표현을 검색하려면 결과

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 

답변

2

을 발견해야하는, '1111:0'에 의해 ip를 검색하려는 경우 ' 힘든 시간을 보냅니다. 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이 & 사라 만 0의 가장 큰 블록이 ::로 대체 (IPv6를 완전히 유효합니다). 당신이 20 최고의 비트1111:0 등이 inet addresses를 찾으려면

그러나, 당신은 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 

http://rextester.com/ZFFFK28291

+0

당신이 말한대로, 우리는의 머리 인 오른쪽 ip를 찾을 수 있습니다. 문자열 (1111 : 0) ip가 중간 또는 끝에 일치하면이 방법으로는이 문제를 해결할 수 없습니다. – ggg

+0

@ggg 예,'inet' 내부를 검색 할 수 없습니다. 왜냐하면 출력이 정규화되어 있기 때문입니다. 당신은 canonized 형태의 내부에서 (이론적으로) 검색 할 수 있지만, 그것은 같지 않을 것입니다 (링크 된 rextester 예제를보십시오). – pozs

+0

문자열의 선두 인 ip뿐만 아니라 문자열 '1111 : 0 '이 중간 또는 끝에 있는지 검색 할 수있는 방법을 찾았습니다. – ggg

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:_______' 
+0

하지만이 방법은 f.ex에서'1111 : 0 '을 검색하는 데 어떻게 도움이됩니까? '1111 : 1 : 101 : a : 2 : 3 : 4 : 5'? 이 기능은 한 블록 만 검색하면 작동합니다. 그리고 그러한 경우라면, 하나의 'LIKE'도 사용할 수 있습니다. – pozs