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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7998442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-01 13:07:32  来源:igfitidea点击:

Closing all cursors 'once' from a pl/sql exception block

sqloracleplsqloracle10g

提问by ziggy

Is there an easier way to close all open cursors from within a PL/SQL program (Oracle 10G).

是否有一种更简单的方法可以从 PL/SQL 程序 (Oracle 10G) 中关闭所有打开的游标。

I have a program which can generate a number of exceptions. To exit properly, i need to check whether there are any cursors open and close them. This is the kind of situation i am ending up with.

我有一个程序可以生成许多异常。要正确退出,我需要检查是否有任何游标打开和关闭它们。这就是我要结束的那种情况。

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;

Obviously the above is not ideal especially if there are many exception clauses. Instead of havin the same checks on each exception block, is there a quicker way to close all open cursor? Note: It needs to close only the cursors opened by the currently running pl/sql program because there could be other pl/sql program that could also open cursors.

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

Thanks in advance

提前致谢

回答by Justin Cave

Are you sure that you need to use the explicit cursor syntax in the first place rather than using implicit cursors? If you use implicit cursors, Oracle takes care of opening and closing them automatically. You can declare the query inline or out of line as in the block below

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

In either case, Oracle will automatically take care of closing the cursor when you exit the block.

无论哪种情况,当您退出块时,Oracle 都会自动关闭游标。

If you do need to use explicit cursors for some reason, and assuming that you need to catch multiple different exceptions because you will handle those exceptions differently, you can create a nested block that closes the cursors and just call that from each exception handler

如果出于某种原因确实需要使用显式游标,并假设您需要捕获多个不同的异常,因为您将以不同的方式处理这些异常,您可以创建一个关闭游标的嵌套块,然后从每个异常处理程序中调用它

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;