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

时间:2011-11-03 16:28:35

标签: 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;

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

提前致谢

1 个答案:

答案 0 :(得分: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;

在任何一种情况下,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;