Mengapa Anda menggunakan PL/SQL untuk ini sama sekali? Dari apa yang Anda katakan Anda sedang melakukan beberapa matematika, mengapa tidak melakukannya di SQL saja? Ini juga dapat dilakukan dengan kombinasi INSTR dan SUBSTR tetapi akan lebih indah untuk dilihat dengan 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
Demonstrasi SQL Fiddle dari keluaran REGEXP_SUBSTR
Jika Anda memiliki untuk melakukan ini di PL/SQL Anda harus melakukan dua hal:
- Lihat apakah Anda dapat mendeklarasikan fungsi Anda sebagai deterministik .
- Coba dan manfaatkan sub -permintaan cache .
Tampaknya Anda sudah melakukan 2, tetapi Anda dapat mencoba dan memperluas ini dengan menggunakan klausa 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