Waarom gebruik je hier überhaupt PL/SQL voor? Van wat je hebt gezegd dat je wat wiskunde aan het doen bent, waarom doe je dat niet gewoon in SQL? Dit zal ook mogelijk zijn met een combinatie van INSTR en SUBSTR, maar het is mooier om naar te kijken met 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-demonstratie van REGEXP_SUBSTR-uitvoer
Als je hebt om dit in PL/SQL te doen, moet je twee dingen doen:
- Kijk of je je functie kunt declareren als deterministisch .
- Probeer en profiteer van sub -query cachen .
Het lijkt alsof je er al 2 doet, maar je zou kunnen proberen dit uit te breiden door een WITH-clausule te gebruiken:
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