Pourquoi utilisez-vous PL/SQL pour cela ? D'après ce que vous avez dit, vous faites des calculs, pourquoi ne pas simplement le faire en SQL ? Ce sera également possible avec une combinaison de INSTR et SUBSTR, mais c'est plus joli à regarder avec REGEXP_SUBSTR.
select to_number(regexp_substr(ip, '[^.]+', 1, 1)) * power(2,24)
+ to_number(regexp_substr(ip, '[^.]+', 1, 2)) * power(2,16)
+ to_number(regexp_substr(ip, '[^.]+', 1, 3)) * power(2,8)
+ to_number(regexp_substr(ip, '[^.]+', 1, 4))
, icb.*
, icl.*
from ip_city_block icb
join ip_city_location icl
on icl.locid = icb.locid
where to_number(regexp_substr(ip, '[^.]+', 1, 1)) * power(2,24)
+ to_number(regexp_substr(ip, '[^.]+', 1, 2)) * power(2,16)
+ to_number(regexp_substr(ip, '[^.]+', 1, 3)) * power(2,8)
+ to_number(regexp_substr(ip, '[^.]+', 1, 4))
between icb.startipnum and icb.endipnum
Démonstration SQL Fiddle de la sortie REGEXP_SUBSTR
Si vous avez pour ce faire en PL/SQL, vous devez faire deux choses :
- Vérifiez si vous pouvez déclarer votre fonction en tant que déterministe .
- Essayez de profiter de sub -mise en cache des requêtes .
Il semble que vous en fassiez déjà 2, mais vous pouvez essayer de l'étendre en utilisant une clause WITH :
with the_ip as ( select get_ip_integer('74.253.103.98') as ip from dual )
select the_ip.ip
, icb.*
, icl.*
from ip_city_block icb
join ip_city_location icl
on icl.locid = icb.locid
join the_ip
on the_ip.ip between icb.startipnum and icb.endipnum