计算oracle sql

时间:2016-01-06 17:19:28

标签: oracle11g ip-address

我想在SQL中获取给定ipaddress的十进制值 示例192.168.0.0其十进制表示形式为3232235520IP - DECIMAL

select 
       TO_NUMBER(LISTAGG(binary1, '') WITHIN GROUP ( ORDER BY cnt), 'XXXXXXXX') as Numeric1
from (
     select 1 as grp, rownum as cnt
            , NVL(TRIM(LEADING '0' FROM utl_raw.cast_from_binary_integer(regexp_substr('192.168.255.255','\d+', 1, rownum))), '00') as binary1
          from dual connect by rownum <= 4
     ) temp
group by grp

我正在使用oracle 11g,我已经提出了上述方法。

  1. 使用ult_raw.cast_from_binary_integer将八位字节转换为二进制表示,但内部二进制转换为十六进制表示。因此,内部查询的输出基本上是八位字节的十六进制表示。
  2. 十六进制表示是通过棍棒4 binarys示例(1000) 2 =(8) 16 获得的 因此获取(10001000) 2 的十进制值等于获取(88) 16 的值
  3. 我添加了十六进制表示,保留了cnt列的八位字节顺序,并将结果与​​LISTAGG
  4. 结合在一起

    更新

    我正在使用LISTAGG并通过clauses连接,当我尝试转换1000条记录时,这会有任何性能问题。 this method如建议的那样简单易读,但没有数学解释。 second method这使用PL / SQL函数,我将把它作为我的最后手段。

1 个答案:

答案 0 :(得分:0)

this method的数学解释如下

SELECT
TO_NUMBER(REGEXP_SUBSTR('127.0.0.1','\w+',1,1))*POWER(2,24)
+ TO_NUMBER(REGEXP_SUBSTR('127.0.0.1','\w+',1,2))*POWER(2,16)
+ TO_NUMBER(REGEXP_SUBSTR('127.0.0.1','\w+',1,3))*POWER(2,8)
+ TO_NUMBER(REGEXP_SUBSTR('127.0.0.1','\w+',1,4))*POWER(2,0) IP
FROM
DUAL;
  

假设我有IPADDRESS = 255.127.72.1

二进制表示法 11111111.01111111.01001000.00000001

converting to decimal 

first octet
1.231 + 1.230 + 1.229 + 1.228
+ 1.227 + 1.226 + 1.225 + 1.224

= (1.27 + 1.26 + 1.25 + 1.24 
   + 1.23 + 1.22 + 1.21 + 1.1).224
= (28 - 1).224
= (255).224

second octet
0.223 + 1.222 + 1.221 + 1.220
+ 1.219 + 1.218 + 1.217 + 1.216

= (0.27 + 1.26 + 1.25 + 1.24 
   + 1.23 + 1.22 + 1.21 + 1.1).216
= (27 - 1).216
= (127).216

third octet
0.215 + 1.214 + 0.213 + 0.212
+ 1.211 + 0.210 + 0.29 + 0.28

= (0.27 + 1.26 + 0.25 + 0.24 
   + 1.23 + 0.22 + 0.21 + 0.1).216
= (26 + 1.23).216
= (72).216

similarly the last octet

我能够使用以下方法消除子查询

select sum(regexp_substr('255.127.72.1', '\d+', 1, rownum) * POWER(2, 32 - 8*rownum))  as binary1
          from dual connect by rownum <= 4