顯式游標的處理過程包括:
聲明游標,打開游標,檢索游標,關閉游標。
聲明游標
CURSOR c_cursor_name IS statement;
游標相當於一個查詢結果集,將查詢的結果放在游標里,方便在塊里進行處理。
記錄
一個記錄就是一個復合的數據結構,相當於結果集里的一行數據,用於遍歷游標時存放結果。記錄支持三種定義:基於表,基於游標,自定義。
如果是基於表或游標,其定義格式為:
record_name table_name or cursor_name%ROWTYPE;
打開游標
OPEN cursor_name;
檢索游標
存在兩種游標檢索方式:
FETCH cursor_name INTO pl/sql variables;
or
FETCH cursor_name INTO pl/sql record;
當游標被檢索時,在每個FETCH語句之后,活躍數據集指針繼續遷移到下一個數據行。因此,FETCH會返回活躍數據集中連續的數據行,直到獲取整個數據集。最后一個FETCH語句不會給輸出變量賦值,后者仍舊保存原來的值。
那么在游標檢索到最后,如何停止檢索呢?
這時就要用到游標的屬性了。
游標屬性包括:
%NOTFOUND 當前的FETCH操作沒有返回數據行時,為true,否則為false;
%FOUND 與上述相反;
%ROWCOUNT 返回游標的記錄數量;
%ISOPEN 檢測游標是否打開;
關閉游標
CLOSE cursor_name;
以下是一個示例:
1 declare 2 cursor c_zip is 3 select * from zipcode;--聲明游標 4 vr_zip c_zip%rowtype;--聲明記錄,結構基於游標 5 begin 6 open c_zip;--打開游標 7 loop 8 fetch c_zip into vr_zip;--循環,檢索游標 9 exit when c_zip%NOTFOUND;--利用屬性,當前一FETCH操作沒有返回數據,exit 10 dbms_output.putline(vr_zip.zip || ' ' || vr_zip.city || ' ' || vr_zip.state); 11 end loop; 12 close c_zip;--關閉游標 13 end;
簡便的辦法:使用游標 FOR循環
借助於游標FOR循環,游標打開,檢索和關閉的過程都被隱含地實現。這使得代碼塊更容易編寫與維護。
使用方法其實與C#中的foreach相似,自動遍歷。
以下是上面示例的for循環寫法:
1 declare 2 cursor c_zip is 3 select * from zipcode;--聲明游標 4 begin 5 for r_zip in c_zip--不必聲明記錄 6 loop 7 dbms_output.putline(vr_zip.zip || ' ' || vr_zip.city || ' ' || vr_zip.state); 8 end loop;--不必考慮何時退出 9 end;
傳入參數
如果要傳入參數,在游標名后面加上類似函數的參數列表之類的東西,在檢索游標時相當於調用(即FETCH INTO語句),在游標名后面傳入實際參數。
下面是一個示例:
1 declare 2 cursor c_zip(p_state in zipcode.state%type) is --傳入參數 3 select zip, city, state 4 from zipcode 5 where state = p_state; 6 v_state zipcode.state%type := &a; 7 begin 8 for r_zip in c_zip(v_state)--調用時傳入實際參數 9 loop 10 dbms_output.put_line(r_zip.zip || ', ' || r_zip.city || ', ' || r_zip.state); 11 end loop; 12 exception 13 when no_data_found then dbms_output.put_line('no data found'); 14 end;
七夕節快樂!大家要做好安全措施哦~~
