To port this, you really need to look at the original context of its usage. In the example you've given, the cursors are easily replaced with simple selects. The original code:
-- Check if the address is an orphan
open address_is_orphan_p_cursor(address_id => v_addresses_located_row.address_id);
fetch address_is_orphan_p_cursor into v_address_is_orphan_p;
close address_is_orphan_p_cursor;
if v_address_is_orphan_p = 't' then
-- Delete the address's subplace_relation
open subplace_rel_cursor(address_id => v_addresses_located_row.address_id);
fetch subplace_rel_cursor into v_rel_id;
if not subplace_rel_cursor%NOTFOUND then
subplace_rel.delete(v_rel_id);
end if;
close subplace_rel_cursor;
-- Delete the address itself
pl_address.delete(v_addresses_located_row.address_id);
end if;
Can be replaced with:
select
count(*) = 0
into
v_address_is_orphan_p
from
place_element_map
where
place_id = v_addresses_located_row.address_id;
if v_address_is_orphan_p then
select
sr.rel_id
into
v_rel_id
from
subplace_rels sr, acs_rels ar
where
ar.rel_id = sr.rel_id
and
ar.object_id_two = v_addresses_located_row.address_id;
if FOUND then
PERFORM subplace_rel__delete(v_rel_id);
end if;
PERFORM pl_address__delete(v_addresses_located_row.address_id);
end if;
In addition, v_address_is_orphan_p needs to change from char(1) to boolean. Notice that the decode(... statement was replaced with select count(*) = 0. This evaluates to either 't' or 'f' depending on the value of count(*). This is a short-cut for converting decodes that evaluate to a simple boolean values. For more complex decodes, you need to use a case statement to port a decode statement. Something like:
select
case when count(*) = 0 then 't'
when count(*) = 3 then 't'
else 'f' end into v_foo
...
The above case statement returns true values for counts of 0 and 3 and it is equivalent to decode(count(*),0,'t',3,'t','f').