从pl/sql异常块关闭所有游标'once'

zig*_*ggy 2 sql oracle plsql oracle10g

是否有更简单的方法可以从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;
Run Code Online (Sandbox Code Playgroud)

显然,如果有许多例外条款,上述情况并不理想.而不是对每个异常块进行相同的检查,是否有更快的方法来关闭所有打开的游标?注意:它只需要关闭当前运行的pl/sql程序打开的游标,因为可能还有其他pl/sql程序也可以打开游标.

提前致谢

Jus*_*ave 11

您确定首先需要使用显式游标语法而不是使用隐式游标吗?如果使用隐式游标,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;
Run Code Online (Sandbox Code Playgroud)

在任何一种情况下,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;
Run Code Online (Sandbox Code Playgroud)