2011-11-03 47 views
2

是否有一種更簡單的方法來關閉PL/SQL程序(Oracle 10G)中的所有打開的遊標。從pl/sql異常塊中關閉所有遊標'一次'

我有一個程序可以產生一些例外。要正常退出,我需要檢查是否有 任何遊標打開和關閉它們。這是我結束的那種情況。

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

不太熟悉Oracle異常語法,但是您能否將所有的遊標關閉語句放在一邊測試您正在處理的異常類型? – n8wrl

+0

否,因爲發生異常時,控制權跳轉到相關異常塊的第一行。在某些情況下,我無法控制何時會引發異常。 – ziggy

回答

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; 
+0

在某些情況下可能不會。我正在嘗試更改現有代碼,因此需要時間將所有顯式遊標更改爲隱式。 要解決打開的遊標問題,我想通過控制從一個地方關閉現有的遊標來最大限度地減少錯誤的範圍。 – ziggy

+0

@ziggy - 發佈一個可以從每個異常處理程序調用以關閉所有遊標的嵌套塊的示例。這至少給你一個位置來放置所有的清理邏輯。 –

+0

是的,應該工作。 我想現在要做的最好的事情是避免顯式遊標。謝謝! – ziggy