首页 > 代码库 > 针对ip地址排序的解决办法

针对ip地址排序的解决办法

      近期开发中遇到对ip地址进行排序问题,普通的按字符串排序不能满足要求,网上查阅资料,大都是把ip地址分段截取,然后排序,方法比较复杂。咨询公司大牛,通过oracle中定义TYPE 和Type Body实现,基本思路就是把字符串类型转成整型,然后比较。

     代码如下:

CREATE OR REPLACE TYPE "IP_TYPE"      as object( /*------------------------------------------------------------------------------  功能要求:处理IP格式(如:10.67.21.201)的字符串。  参数定义:  数据来源:  调用方法:其它语言中调用,PL/SQL过程中  特除说明:  ----------------------------------------------------------------------------------*/    IPstr varchar2(15),--IP地址    IPnum int,--对应的数值    constructor function IP_type(p_str varchar2) return self as result,    constructor function IP_type(p_num int) return self as result,    member function increase(p_num int) return IP_type,    member function toString return varchar2,    member function toNumber return int,   order  member function order_fun(p_obj IP_type) return int )

 

create or replace type  body IP_type  is /*------------------------------------------------------------------------------  功能要求:IP_type对象的各函数实现。  参数定义:  数据来源:  调用方法:其它语言中调用,PL/SQL过程中  特除说明:  ----------------------------------------------------------------------------------*/   /*------------------------------------------------------------------------------   功能要求:实现将IP地址转换成对应的数值     ----------------------------------------------------------------------------------*/   constructor function IP_type(p_str varchar2) return self as result    is       type t_tab is table of binary_integer index by binary_integer;       l_tab  t_tab;       function split(p_str varchar2, p_token char:=.) return t_tab as         l_n    pls_integer := 0;         l_idx  pls_integer := 0;         l_args varchar2(1000) := p_str;         tab  t_tab;       begin         if substr(l_args, -1, 1) <> p_token then           l_args := l_args || p_token;         end if;         loop           l_n := instr(l_args, p_token);           exit when(nvl(l_n, 0) = 0);           l_idx := l_idx + 1;           tab(l_idx) := ltrim(rtrim(substr(l_args, 1, l_n - 1)));           l_args := substr(l_args, l_n + 1);         end loop;         return tab;       end;   begin     l_tab:=split(p_str);     if l_tab.count=4 then       self.IPstr:=p_str;       for i in 1 .. l_tab.count       loop         self.IPnum:=nvl(self.IPnum,0)+l_tab(i)*power(256,4-i);       end loop;     end if;     return;   end;   /*------------------------------------------------------------------------------   功能要求:实现将数值转换成对应的IP地址     ----------------------------------------------------------------------------------*/   constructor function IP_type(p_num int) return self as result   is    l_first int:=floor(p_num/power(256,3));   begin     if l_first<255 then     self.ipnum:=p_num;     self.IPstr:=l_first||.||                floor(mod(p_num,power(256,3))/power(256,2))||.||                floor(mod(p_num,power(256,2))/power(256,1))||.||                floor(mod(p_num,power(256,1)));     else     self.ipnum:=0;     self.IPstr:=0.0.0.0;     end if;     return;   end;   /*------------------------------------------------------------------------------     ----------------------------------------------------------------------------------*/   member function increase(p_num int) return IP_type   is   begin      return IP_type(self.ipnum+p_num);   end;   member function toString return varchar2   is   begin    return IPstr;   end;   /*------------------------------------------------------------------------------   功能要求:得到当前IP地址对应的数值     ----------------------------------------------------------------------------------*/  member function toNumber return int   is   begin    return IPnum;   end;   /*------------------------------------------------------------------------------     ----------------------------------------------------------------------------------*/   order  member function order_fun(p_obj IP_type) return int   is   begin      return sign(self.IPnum-p_obj.IPnum);   end; end;

具体使用方式:
 select ip_type(‘10.67.2.101‘).ipnum,ip_type(‘10.67.2.101‘).ipstr from dual

返回结果:172163685,10.67.2.101

 

针对ip地址排序的解决办法