Proč k tomu vůbec používáte PL/SQL? Z toho, co jste řekl, že děláte nějakou matematiku, proč to neudělat jen v SQL? To bude také možné s kombinací INSTR a SUBSTR, ale na pohled je to hezčí s 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
Ukázka SQL Fiddle výstupu REGEXP_SUBSTR
Pokud máte Chcete-li to provést v PL/SQL, měli byste udělat dvě věci:
- Podívejte se, zda můžete svou funkci deklarovat jako deterministický .
- Vyzkoušejte a využijte výhod sub -ukládání dotazů do mezipaměti .
Zdá se, že už děláte 2, ale můžete to zkusit rozšířit pomocí klauzule 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