从pl/sql异常块“一次”关闭所有游标

从pl/sql异常块“一次”关闭所有游标,sql,oracle,plsql,oracle10g,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 clos

在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程序


提前感谢

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

不太熟悉Oracle异常语法,但在测试正在处理的异常类型之前,是否可以放置所有游标关闭语句?否,因为当引发异常时,控件会跳到相关异常块的第一行。在某些情况下,我无法控制何时引发异常。在某些情况下可能无法控制。我正在尝试更改现有代码,以便将所有显式游标更改为隐式游标需要时间。为了解决“打开游标”问题,我希望通过控制从一个位置关闭现有游标来最小化错误范围。@ziggy-发布了一个嵌套块的示例,可以从每个异常处理程序调用该嵌套块来关闭所有游标。这至少给了你一个单一的位置来放置所有的清理逻辑。是的,这应该是可行的。我想从现在开始最好的办法是避免显式游标。谢谢