是否有更简单的方法可以从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程序,也可以打开游标。
提前致谢
答案 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;