I think Oracle will try to cache the results of your tbl_keys
subquery, so if it returns a small number of rows, your queries are probably fine the way they are.
I don't know if it's better, but if you're having performance problems an alternate method you could try is to join the tables, e.g.
open curr1 for
select t.*
from table1 t
join tbl_keys k
on k.key_field = t.key_field
and k.type = 1;
This might improve performance if your tbl_keys table is very large.
Personally, I prefer using implicit cursor loops whenever possible - they're simple and can be very fast - but I don't know if it would work for your procedure, since you didn't show the rest of it.
for r in (select t.*
from table1 t
join tbl_keys k
on k.key_field = t.key_field
and k.type = 1)
loop
-- output the row somehow
end loop;
for r in (select t.*
from table2 t
join tbl_keys k
on k.key_field = t.key_field
and k.type = 1)
loop
-- output the row somehow
end loop;
...etc