遊標是一個指向存儲有SELECT
或DML語句處理信息的私有SQL區域的指針。在使用SQL時數據庫在大部分時候自動維護遊標,但是也可以人爲的操作遊標。
顯式的定義遊標
通過在DECLARE
區域使用CURSOR IS
聲明遊標,和表與視圖一樣,可以基於遊標聲明記錄類型的變量。
DECLARE
CURSOR cursor_name
IS
SELECT *
FROM table_name;
cursor_record cursor_name%ROWTYPE;
BEGIN
OPEN cursor_name;
LOOP
FETCH cursor_name INTO cursor_record;
EXIT WHEN cursor_name%NOTFOUND;
statements;
END LOOP;
CLOSE cursor_name;
END;
遊標聲明後,在使用時,需要首先打開遊標OPEN cursor_name;
,然後才能提取數據FETCH cursor_name INTO cursor_record;
,除了把數據提取進入記錄中,也可以通過INTO
後跟多個變量的方式把數據提取進多個變量中,使用完遊標後,需要關閉遊標CLOSE cursor_name;
,對於直接在包級別定義的遊標,在打開遊標後,除非直到主動關閉或者當前的數據庫會話結束,否則遊標不會被關閉,而對於在過程或函數中定義的遊標,在過程或函數結算後,遊標會自動關閉,但是更推薦的做法是無論在哪裏定義的遊標,使用完後都顯式地關閉。
如果遊標的查詢不能夠對應到任何數據,遊標屬性cursor_name%NOTFOUND
返回TRUE
,類似的遊標還有屬性cursor_name%FOUND
在查詢到數據時候返回TRUE
,cursor_name%ROWCOUNT
返回調用時提取的記錄數,cursor_name%ISOPEN
遊標打開時返回TRUE
。
遊標變量
遊標變量顧名思義就是指向遊標的變量,遊標變量與遊標不同,遊標本身不是變量,所以遊標不能作爲參數傳遞到過程或函數中,但是遊標變量卻可以。
通過SYS_REFCURSOR
聲明遊標變量
DECLARE
cursor_variable_name SYS_REFCURSOR;
table_record table_name%ROWTYPE;
BEGIN
OPEN cursor_variable_name FOR
SELECT *
FROM table_name;
LOOP
FETCH cursor_variable_name INTO table_record;
EXIT WHEN cursor_variable_name%NOTFOUND;
statements;
END LOOP;
CLOSE cursor_variable_name;
END;
遊標變量使用OPEN FOR
的語法指定其指向的遊標並且打開遊標,其他操作和遊標一致。
OPEN FOR
支持其指定的遊標以變量表示,所以可以實現動態SQL的效果。
CREATE OR REPLACE FUNCTION
dynamic_sql (query_in IN VARCHAR2)
RETURN SYS_REFCURSOR
IS
cursor_variable SYS_REFCURSOR;
BEGIN
OPEN cursor_variable FOR query_in;
RETURN cursor_variable;
END dynamic_sql;
之後可以傳入任意SQL,獲取對應的遊標變量
BEGIN
dynamic_sql('select * from table_name');
END;