Вы уверены, что вам нужно в первую очередь использовать явный синтаксис курсора, а не неявные курсоры? Если вы используете неявные курсоры, Oracle позаботится об их открытии и закрытии автоматически. Вы можете объявить запрос как в строке, так и вне строки, как показано в блоке ниже
DECLARE
CURSOR cursor_a
IS SELECT *
FROM emp;
BEGIN
FOR a IN cursor_a
LOOP
<<do something>>
END LOOP;
FOR b IN (SELECT *
FROM dept)
LOOP
<<do something else>>
END LOOP;
END;
В любом случае Oracle автоматически позаботится о закрытии курсора при выходе из блока.
Если вам по какой-то причине нужно использовать явные курсоры и предполагать, что вам нужно перехватывать несколько разных исключений, потому что вы будете обрабатывать эти исключения по-разному, вы можете создать вложенный блок, закрывающий курсоры, и просто вызывать его из каждого исключения обработчик
DECLARE
CURSOR cursor_a
IS SELECT *
FROM emp;
CURSOR cursor_b
IS SELECT *
FROM dept;
PROCEDURE close_open_cursors
AS
BEGIN
IF( cursor_a%isopen )
THEN
close cursor_a;
END IF;
IF( cursor_b%isopen )
THEN
close cursor_b;
END IF;
END;
BEGIN
OPEN cursor_a;
OPEN cursor_b;
RAISE no_data_found;
EXCEPTION
WHEN no_data_found
THEN
close_open_cursors;
<<do something meaningful>>
WHEN too_many_rows
THEN
close_open_cursors;
<<do something meaningful>>
WHEN others
THEN
close_open_cursors;
raise;
END;