遊標分為隱式遊標和顯示遊標。
一、隱式遊標
對於select * into和DML操作(update、delete、insert)都附帶有一個隱式遊標。
隱式遊標的屬性
SQL%ROWCOUNT 整型 代表DML語句成功執行的資料行數
SQL%FOUND 布爾型 值為TRUE代表插入、刪除、更新或單行查詢操作成功
SQL%NOTFOUND 布爾型 與SQL%FOUND屬性傳回值相反
SQL%ISOPEN 布爾型 DML執行過程中為真,結束後為假
當系統使用一個隱式遊標時,可以通過隱式遊標的屬性來瞭解操作的狀態和結果,進而控製程序的流程。隱式遊標可以使用名字SQL來訪問,但要注意,通過SQL遊標名總是只能訪問前一個DML操作或單行SELECT操作的遊標屬性。所以通常在剛剛執行完操作之後,立即使用SQL遊標名來訪問屬性。
例子:
--/
DECLARE
v_emp emp%rowtype;
BEGIN
delete from emp where empno = 9999;
IF SQL%notfound THEN
dbms_output.put_line('隱式遊標 屬性為notfound');
END IF;
dbms_output.put_line('delete無記錄不會出現異常');
END;
/
運行結果:
隱式遊標 屬性為notfound
delete無記錄不會出現異常
二、顯式遊標
1、遊標的使用有4個步驟:
1)聲明遊標
CURSOR 遊標名(參數1, 參數2, ... , 參數n) IS select語句;
2)開啟遊標
OPEN 遊標名;
3)提取資料
FETCH 遊標名 INTO 變數1, 變數2 ...
或
FETCH 遊標名 INTO 記錄變數;
4)關閉遊標
CLOSE 遊標名;
例子:
--/
DECLARE
CURSOR c_emp IS select * from emp; --聲明遊標
v_emp c_emp%rowtype;
--v_emp emp%rowtype;
BEGIN
OPEN c_emp; --開啟遊標
LOOP
FETCH c_emp INTO v_emp; --提取資料
EXIT WHEN c_emp%notfound;
dbms_output.put_line(v_emp.empno);
END LOOP;
CLOSE c_emp; --關閉遊標
END;
/
說明:
1)關於退出迴圈的判斷
如果用以下方式寫:
EXIT WHEN c_emp%notfound;
FETCH c_emp INTO v_emp; --提取資料
v_emp中的值會多列印一次。
c_emp取到最後一條記錄,然後再次迴圈,此時先判斷c_emp是否為空白,c_emp不為空白,再fetch資料,此時遊標才為空白,v_emp中的記錄不變,所以會多列印一行。
2)關於記錄變數的定義
v_emp c_emp%rowtype;
和
v_emp emp%rowtype;
兩種方式都可以。
2、遊標迴圈
1)第一種方式,就是把遊標的4個步驟都做一遍
2)第二種方式,使用for迴圈遍曆
--/
DECLARE
CURSOR c_emp IS select * from emp;
BEGIN
FOR v_emp IN c_emp
LOOP
dbms_output.put_line(v_emp.ename);
END LOOP;
END;
/
這個小程式裡面,只有遊標的聲明,for迴圈中省略了遊標的開啟、資料提取、關閉。記錄變數的聲明也省略了。
3)第三種方式,更簡單的for迴圈遍曆
--/
BEGIN
FOR re IN select * from emp
LOOP
dbms_output.put_line(re.ename);
END LOOP;
END;
/
這個小程式裡面,省略了遊標的聲明、開啟、資料提取、關閉。記錄變數的聲明也省略了。
3、顯式遊標屬性
雖然可以使用前面的形式獲得遊標資料,但是在遊標定義以後使用它的一些屬性來進行結構控制是一種更為靈活的方法。顯式遊標的屬性如下所示。
使用方法:
遊標名%屬性
顯式遊標的屬性
%ROWCOUNT 整型 獲得FETCH語句返回的資料行數
%FOUND 布爾型 最近的FETCH語句返回一行資料則為真,否則為假
%NOTFOUND 布爾型 與%FOUND屬性傳回值相反
%ISOPEN 布爾型 遊標已經開啟時值為真,否則為假
小結:
使用遊標可以先聲明這個遊標,然後使用簡便的for迴圈來遍曆資料。