位於內存中的 "臨時表"
。 具體以下:遊標是從數據表中提取出來的數據,以 臨時表 的形式存放到 內存中
,在遊標中有一個 數據指針, 在初始狀態下指向的是首記錄,利用 fetch
語句能夠移動該指針,從而對遊標中的數據進行各類操做,而後將操做結果寫回到數據庫中。遊標的本質是一個結果集resultset,主要用來臨時存儲從數據庫中提取出來的數據塊。sql
1. 顯式遊標:由用戶定義,須要的操做:定義遊標、打開遊標、提取數據、關閉遊標,主要用於對查詢語句的處理。數據庫
2.顯式遊標的屬性oop
(1) %NOTFOUND。表示遊標獲取數據的時候是否有數據提取出來,沒有數據返回TRUE,有數據返回false。常常用來判斷遊標是否所有循環完畢,如案例1%NOTFOUND爲true的時候,說明循環完畢,跳出LOOP循環。測試
(2) %FOUND。正好和%NOTFOUND相反,當遊標提取數據值時有值,返回TRUE,不然返回FALSE。fetch
(3) %ISOPEN。用來判斷遊標是否打開。spa
(4) %ROWCOUNT。表示當前遊標FETCH INTO獲取了多少行的記錄值,用來作計數用的。指針
舉例:打印表hu_test中的指定字段code
--顯示遊標 declare cursor hu_test_cursor is select owner,object_type,created from hu_test;--定義遊標 v_owner hu_test.owner%type; v_object_type hu_test.object_type%type; v_created hu_test.created%type; begin open hu_test_cursor;--打開遊標 loop fetch hu_test_cursor into v_owner,v_object_type,v_created;--提取數據 dbms_output.put_line('全部者:'||v_owner||' 類型是:'||v_object_type||' 建立時間:'||v_created); exit when hu_test_cursor%notfound; end loop; close hu_test_cursor;--關閉遊標 EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLCODE || ' : ' || SQLERRM);--返回錯誤消息 dbms_output.put_line(dbms_utility.format_error_backtrace);--返回錯誤行 end;
舉例:檢驗遊標是否打開,打開的話顯示提取行數orm
--檢驗遊標是否打開,打開的話顯示提取行數 declare cursor hu_test_cursor is select owner,object_type,created from hu_test;--定義遊標 v_owner hu_test.owner%type; v_object_type hu_test.object_type%type; v_created hu_test.created%type; begin open hu_test_cursor;--打開遊標 loop fetch hu_test_cursor into v_owner,v_object_type,v_created;--提取數據 dbms_output.put_line('全部者:'||v_owner||' 類型是:'||v_object_type||' 建立時間:'||v_created); exit when hu_test_cursor%notfound; end loop; if(hu_test_cursor%isopen) then DBMS_OUTPUT.PUT_LINE('遊標已打開'); DBMS_OUTPUT.PUT_LINE('讀取了'||hu_test_cursor%ROWCOUNT||'行'); else DBMS_OUTPUT.PUT_LINE('遊標沒有打開'); end if; close hu_test_cursor;--關閉遊標 EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLCODE || ' : ' || SQLERRM);--返回錯誤消息 dbms_output.put_line(dbms_utility.format_error_backtrace);--返回錯誤行 end;
3. 隱式遊標:由系統定義併爲它建立工做區域,而且隱式的定義打開提取關閉,隱式遊標的遊標名就是'SQL',屬性和顯示遊標相同,主要用於對單行select語句或dml操做進行處理。blog
(1)SQL%ISOPEN:遊標是否開啓
, true:開啓,false:關閉
(2)SQL%FOUND:前一個 fetch 語句是否有值
,true:有,false:沒有
(3)SQL%NOTFOUND:與上述相反,常被用於 退出循環
,true:沒有,false:有, null : 空。注意哦,只有 爲 true 時,才退出(當 第一次 fetch 爲 null 時,不會退出!)
(4)SQL%ROWCOUNT:當前成功執行的數據行數(非總記錄數
)
舉例:用隱式遊標測試插入,更新,刪除,查詢等
--隱式遊標 declare v_count number; begin insert into hu_test(owner,object_type,created) values('SYS','test',sysdate); IF SQL%FOUND THEN dbms_output.put_line('插入成功!'); commit; END IF; update hu_test e set e.object_type='CLUSTER1' where e.object_type='CLUSTER'; IF SQL%FOUND THEN dbms_output.put_line('更新成功!'); commit; END IF; delete from hu_test e where e.object_id=3; IF SQL%FOUND THEN dbms_output.put_line('刪除成功!'); commit; END IF; select count(*) into v_count from hu_test; IF SQL%FOUND THEN dbms_output.put_line('總記錄爲: '||v_count); END IF; IF SQL%ISOPEN THEN dbms_output.put_line('可手動查看'); ELSE dbms_output.put_line('沒法手動查看'); END IF; EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLCODE || ' : ' || SQLERRM); dbms_output.put_line(dbms_utility.format_error_backtrace); end;
4.遊標FOR循環:隱含的執行了打開提取關閉數據,代碼精簡不少,syntax:
FOR table_record IN table_cursor LOOP STATEMENT; END LOOP;
舉例:遊標FOR循環
DECLARE cursor hu_test_cursor is select owner,object_type,created from hu_test; BEGIN FOR test_cursor IN hu_test_cursor LOOP dbms_output.put_line('全部者:'||test_cursor.owner||' 類型是:'||test_cursor.object_type||' 建立時間:'||test_cursor.created); END LOOP; END;
這裏遊標FOR循環省去了對於取到的數據的變量的命名和賦值,同時若是所有打印則不用寫循環條件,代碼精簡了不少。
若是想讓代碼更加精簡,則能夠去掉對遊標的聲明引入子查詢便可,操做以下。
--更簡便的for循環 BEGIN FOR test_cursor IN (select owner,object_type,created from hu_test) LOOP dbms_output.put_line('全部者:'||test_cursor.owner||' 類型是:'||test_cursor.object_type||' 建立時間:'||test_cursor.created); END LOOP; END;
5.參數遊標,動態遊標1
舉例:輸入object_id查詢相關數據
--參數遊標 declare cursor hu_test_cursor(numid number) is select owner,object_type,created from hu_test e where e.object_id=numid; BEGIN FOR test_cursor IN hu_test_cursor(&numid) LOOP--這裏也能夠用一個變量來賦值 dbms_output.put_line('全部者:'||test_cursor.owner||' 類型是:'||test_cursor.object_type||' 建立時間:'||test_cursor.created); END LOOP; END;
6.參數遊標,動態遊標2
--動態遊標 declare v_id hu_test.object_id%type; v_sql varchar2(2000); type test_cursor_type is ref cursor; test_cursor test_cursor_type; v_owner hu_test.owner%type; v_object_type hu_test.object_type%type; v_created hu_test.created%type; BEGIN v_id:=20; v_sql:='select owner,object_type,created from hu_test e where e.object_id = :v_id'; open test_cursor for v_sql using v_id; loop fetch test_cursor into v_owner,v_object_type,v_created; exit when test_cursor%notfound; dbms_output.put_line('全部者:'||v_owner||' 類型是:'||v_object_type||' 建立時間:'||v_created); END LOOP; close test_cursor; EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLCODE || ' : ' || SQLERRM); dbms_output.put_line(dbms_utility.format_error_backtrace); END;