游標在操作數據庫時經常用到的。它使用相對靈活。游標--數據的緩沖區。游標的使用可以讓用戶像操作數組一樣操作查詢出來的數據集,這使得使用PL/SQL更加方便。實際上,它提供了一種從集合性質的結果中提取單條記錄的手段。
游標的概念
可以將游標(Cursor)形象地看做成一個變動的光標。它實際上是一個指針,它在一段Oracle存放數據查詢結果集或數據操作結果集的內存中,這個指針可以指向結果集中的任何一條記錄 。這樣就可以得到它所指向的數據了,但初始時它指向首記錄。這種模型很像編程語言中的數組。
可以簡單的理解游標為指向結果集記錄的指針,利用游標可以把返回它當前指向 的行記錄(只能返回一行記錄)。如果要返回多行,那么需要不斷滾動游標,把想要的數據查詢一遍。用戶可以操作游標所在位置行的記錄。
游標的種類
Oracle中游標分為靜態游標和REF游標。其中,靜態游標就像一個數據快照,打開游標后的結果集是對數據庫數據的一個備份,數據不隨着對表執行DML操作而改變。從這個特性來說,結果集是靜態的。
靜態游標包含如下兩種類型:
顯式游標:是指在使用前必須有着明確的游標聲明和定義,這樣的游標定義會關聯數據查詢語句,通常會返回一行或多行。打開游標后,用戶可以利用游標的位置對結果集進行檢索,使之返回單一的行記錄,用戶可以操作次記錄。關閉游標后,就不能再對結果集進行任何操作。顯式游標需要用戶自己寫代碼完成,一切由用戶控制。
隱式游標:和顯式游標不同,它被PL/SQL自動管理,也被稱為PL/SQL游標。由Oracle自動管理。該游標用戶無法控制,但能得到它的屬性信息。
顯式游標
顯式游標在PL/SQL編程中有着重要的作用,通過顯式游標用戶可以操作返回的數據,使得一些在編程語言復雜的功能變得更容易實現。游標的語法:
CURSOR cursor_name
[(parameter_name,dataTYPE,...)]
IS select_statement ;
語法說明:CURSOR : 聲明游標關鍵字;cursor_name: 游標的名字 ;
parameter_name: 參數名稱;dataTYPE: 參數類型;
select_statement :游標關聯的SELECT語句,但該語句不能是SELECT....INTO ...語句
游標使用步驟
顯式游標的使用順序可以明確的分成聲明游標、打開游標、讀取數據和關閉游標4個步驟。
(1)聲明游標
主要用來給游標命名並且使得游標關聯一個查詢。具體語句:
DECLARE
CURSOR stunames IS SELECT s.sname FROM student s ;
stuname student.sname%TYPE;
(2)打開游標
游標 中任何對數據的操作都是建立在游標被打開的前提下。打開游標初始化了游標指針,游標一旦打開,其結果集都是靜態的。也就是說,結果集此時不會反映出數據庫中對數據進行的增加、刪除和修改操作。語法:
OPEN stunames ;
(3)讀取數據
讀取數據需要使用FETCH語句完成,它可以把游標執行位置的記錄放到 PL/SQL聲明的變量當中。它只能讀取指針當前行的記錄。正常情況下,FETCH要和循環語句一起使用,這樣指針會不斷前進,知道某個條件不符合要求而退出。使用FETCH時游標屬性%ROWCOUNT會不斷累加。具體用法:
FETCH stunames INTO stuname ;
(4)關閉游標
關閉某個名稱的游標。此時釋放資源,結果集中的數據將不能做任何操作。
CLOSE stunames;
游標中的LOOP語句
通常顯式游標提取的數據不會是一條記錄,而是多條記錄。這樣就需要一個遍歷結果集的標准方法,而LOOP語句就能實現這樣的功能。
完整的示例:
使用BULK COLLECT 和FOR 語句的游標
游標中通常使用FETCH....INTO...語句提取數據,這種方式是單條數據提取,在數據量很大的情況下執行效率不是很理想。而FETCH.....BULK COLLECT INTO...語句可以批量提取數據,在數據量很大的情況下它的執行效率比單條提取數據的高。
使用CURSOR FOR LOOP
游標很多機會都是迭代結果集,在PL/SQL這個過程中可以使用更簡單的方式實現,CURSOR FOR LOOP不需要特別的聲明變量,它可以提出行對象的數據
顯式游標的屬性
利用游標屬性可以得到游標執行的相關信息。顯式游標由4個屬性:
- %ISOPEN:用於判斷游標是否打開,如果已經打開則返回TRUE,如果游標未打開則返回FALSE。
- %FOUND:可用來檢測行數據是否有效。如果有效該屬性返回TRUE,否則返回FALSE。
- %NOTFOUND :與%FOUND屬性恰好相反,如果沒有提取出數據則返回TRUE,否則返回FALSE。
- %ROWCOUNT:累計到當前為止使用FETCH提取數據的行數。
注意: --dbms_output.put_line() 只能打印數字和字符串......
帶參數的游標
在使用顯式游標時可以指定參數,指定的參數可以傳遞給游標使用,這樣就方便根據不同的查詢條件進行查詢,也方便游標在存儲過程中使用。