Защо изобщо използвате PL/SQL за това? От това, което казахте, правите малко математика, защо просто не го направите в SQL? Това също ще бъде възможно с комбинация от INSTR и SUBSTR, но е по-красиво да се гледа с 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
Демонстрация на SQL Fiddle на REGEXP_SUBSTR изход
Ако имате за да направите това в PL/SQL, трябва да направите две неща:
- Вижте дали можете да декларирате функцията си като детерминистичен .
- Опитайте и се възползвайте от sub -кеширане на заявки .
Изглежда, че вече правите 2, но можете да опитате и да разширите това, като използвате клауза 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