近期开发中遇到对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
时间: 2024-10-15 14:27:04