Закрытие всех курсоров «один раз» из блока исключений pl / sql - PullRequest
2 голосов
/ 03 ноября 2011

Существует ли более простой способ закрыть все открытые курсоры из программы PL / SQL (Oracle 10G).

У меня есть программа, которая может генерировать ряд исключений. Чтобы правильно выйти, мне нужно проверить, есть ли любые курсоры открывают и закрывают их. Это та ситуация, с которой я сталкиваюсь.

Procedure test
is 
--
---
Begin
--
--
Exception
 when no_data_found then
    if cursorA%isopen close
    if cursorB%isopen close
    if cursorC%isopen close
 when invalid_date then
    if cursorA%isopen close
    if cursorB%isopen close
    if cursorC%isopen close
 when invalid_user then
    if cursorA%isopen close
    if cursorB%isopen close
    if cursorC%isopen close
 when others then
    if cursorA%isopen close
    if cursorB%isopen close
    if cursorC%isopen close 

End test;

Очевидно, что вышеупомянутое не идеально, особенно если есть много исключительных положений. Вместо того, чтобы иметь одинаковые проверки для каждого блока исключения, есть ли более быстрый способ закрыть весь открытый курсор? Примечание: он должен закрывать только курсоры, открытые текущей запущенной программой pl / sql, потому что могут быть другие Программа pl / sql, которая также может открывать курсоры.

Заранее спасибо

1 Ответ

11 голосов
/ 03 ноября 2011

Вы уверены, что вам нужно в первую очередь использовать явный синтаксис курсора, а не неявные курсоры? Если вы используете неявные курсоры, 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...