Warum verwenden Sie dafür überhaupt PL/SQL? Nach dem, was Sie gesagt haben, machen Sie etwas Mathematik, warum tun Sie das nicht einfach in SQL? Das geht auch mit einer Kombination aus INSTR und SUBSTR, ist aber schöner anzusehen mit 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-Demonstration der REGEXP_SUBSTR-Ausgabe
Wenn Sie haben Um dies in PL/SQL zu tun, sollten Sie zwei Dinge tun:
- Prüfen Sie, ob Sie Ihre Funktion als deklarieren können deterministisch .
- Probieren Sie aus und nutzen Sie sub -Abfrage-Caching .
Es sieht so aus, als ob Sie bereits 2 tun, aber Sie könnten versuchen, dies zu erweitern, indem Sie eine WITH-Klausel verwenden:
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