在oracle中,游標是一種機制,是通過關鍵字CURSOR的來定義一組Oracle查詢出來的數(shù)據(jù)集,可以把查詢的數(shù)據(jù)集存儲在內(nèi)存當中,然后通過游標指向其中一條記錄,通過循環(huán)游標達到循環(huán)數(shù)據(jù)集的目的。
本教程操作環(huán)境:Windows7系統(tǒng)、Oracle 11g版、Dell G3電腦。
在Oracle中,游標(Cursors)是一種機制,可以通過該機制將名稱分配給select語句并處理該sql語句中的信息。
Oracle游標是通過關鍵字CURSOR的來定義一組Oracle查詢出來的數(shù)據(jù)集,類似數(shù)組一樣,把查詢的數(shù)據(jù)集存儲在內(nèi)存當中,然后通過游標指向其中一條記錄,通過循環(huán)游標達到循環(huán)數(shù)據(jù)集的目的。
游標有什么作用?
①指定結(jié)果集中特定行的位置。
②基于當前的結(jié)果集位置檢索一行或連續(xù)的幾行。
③在結(jié)果集的當前位置修改行中的數(shù)據(jù)。
④對其他用戶所做的數(shù)據(jù)更改定義不同的敏感性級別。
⑤可以以編程的方式訪問數(shù)據(jù)庫。
Oracle游標的類型?
1、靜態(tài)游標:結(jié)果集已經(jīng)確實(靜態(tài)定義)的游標。分為隱式和顯示游標
-
隱式游標:所有DML語句為隱式游標,通過隱式游標屬性可以獲取SQL語句信息。
-
顯示游標:用戶顯示聲明的游標,即指定結(jié)果集。當查詢返回結(jié)果超過一行時,就需要一個顯式游標。
2、REF游標:動態(tài)關聯(lián)結(jié)果集的臨時對象。
Oracle游標的狀態(tài)有哪些,怎么使用游標屬性?
?①游標的狀態(tài)是通過屬性來表示。
-
? %Found :Fetch語句(獲取記錄)執(zhí)行情況True or False。
-
? %NotFound : 最后一條記錄是否提取出True or False。
-
? %ISOpen : 游標是否打開True or False。
-
? %RowCount :游標當前提取的行數(shù) 。
?②使用游標的屬性。
? 例子:
/*?conn?scott/tiger?*/ ??Begin ???Update?emp?Set??SAL?=?SAL?+?0.1??Where?JOB?=?'CLERK'; ???If??SQL%Found??Then ????DBMS_OUTPUT.PUT_LINE('已經(jīng)更新!'); ???Else ????DBMS_OUTPUT.PUT_LINE('更新失敗!'); ???End??If; ??End;
如何使用顯示游標,?如何遍歷循環(huán)游標?
1、使用顯示游標
-
聲明游標:劃分存儲區(qū)域,注意此時并沒有執(zhí)行Select 語句。
CURSOR?游標名(?參數(shù)?列表)???[返回值類型]???IS???Select?語句;
-
打開游標:執(zhí)行Select 語句,獲得結(jié)果集存儲到游標中,此時游標指向結(jié)果集頭, 而不是第一條記錄。
?Open?游標名(?參數(shù)?列表);
-
獲取記錄:移動游標取一條記錄
Fetch??游標名InTo??臨時記錄或?qū)傩灶愋妥兞浚?/pre>
-
關閉游標:將游標放入緩沖池中,沒有完全釋放資源。可重新打開。
Close??游標名;
2、遍歷循環(huán)游標
-
for 循環(huán)游標
? ?循環(huán)游標隱式打開游標,自動滾動獲取一條記錄,并自動創(chuàng)建臨時記錄類型變量存儲記錄。處理完后自動關閉游標。
?????For??變量名??In??游標名? ?????Loop ??????數(shù)據(jù)處理語句; ?????End?Loop;
-
Loop循環(huán)游標
?????。。。 ????Loop ?????Fatch??游標名InTo??臨時記錄或?qū)傩灶愋妥兞浚??????Exit??When???游標名%NotFound; ????End???Loop; ?????。。。
? 例子1:
/*?conn?scott/tiger?*/ ???Declare ?????Cursor?myCur?is?select?empno,ename,sal?from?emp; ?????vna?varchar2(10); ?????vno?number(4); ?????vsal?number(7,2); ??Begin ?????open?myCur; ?????fetch?myCur?into?vno,vna,vsal; ?????dbms_output.put_line(vno||'????'||vna||'????'||vsal); ?????close?myCur; ??End; ??/
?例子2:使用loop遍歷游標。
?/*?conn?scott/tiger?*/ ??Declare ?????Cursor?myCur?is?select?ename,job,sal,empno?from?emp; ?????varE?myCur%rowType; ??Begin ?????if?myCur%isopen?=?false?then ????????open?myCur; ???????dbms_output.put_line('Opening...'); ?????end?if; ?????loop ????????fetch?myCur?into?varE; ????????exit?when?myCur%notfound; ????????dbms_output.put_line(myCur%rowCount||'????'||vare.empno||'????'||vare.ename||'????'||vare.sal); ?????end?loop; ?????if?myCur%isopen?then ????????Close?myCur; ????????dbms_output.put_line('Closing...'); ?????end?if; ??End; ??/
? 例子3:使用For循環(huán)遍歷游標,
??/*?conn?scott/tiger?*/ ??Declare ?????Cursor?myCur?is?select?*?from?emp; ??Begin ?????for?varA?in?myCur ??????loop ?????????dbms_output.put_line(myCur%rowCount||'????'||varA.empno||'????'||varA.ename||'??'||varA.sal); ??????end?loop; ??End; ??/
怎樣更新和刪除顯示游標中的記錄?
?①UPDATE或delete語句中的WHERE CURRENT OF子串專門處理要執(zhí)行UPDATE或DELETE操作的表中取出的最近的數(shù)據(jù)。
? 要使用這個方法,在聲明游標時必須使用FOR UPDATE子串,當對話使用FOR UPDATE子串打開一個游標時,
? 所有返回集中的數(shù)據(jù)行都將處于行級(ROW-LEVEL)獨占式鎖定,其他對象只能查詢這些數(shù)據(jù)行,
? 不能進行UPDATE、DELETE或SELECT…FOR UPDATE操作。
? ?在多表查詢中,使用OF子句來鎖定特定的表,如果忽略了OF子句,那么所有表中選擇的數(shù)據(jù)行都將被鎖定。
? ?如果這些數(shù)據(jù)行已經(jīng)被其他會話鎖定,那么正常情況下ORACLE將等待,直到數(shù)據(jù)行解鎖。
?②使用更新或刪除:
? ⑴聲明更新或刪除顯示游標:
???Cursor?游標名IS??SELECT?語句???For?Update?[?Of??更新列列名]; ???Cursor?游標名IS??SELECT?語句???For?Delete?[?Of??更新列列名];
? ⑵使用顯示游標當前記錄來更新或刪除:
???Update??表名???SET???更新語句??Where???Current??Of???游標名; ???Delete??From??表名???Where???Current??Of???游標名;
? ?例子1:更新顯示游標記錄
???/*conn?scott/tiger*/ ???Declare ?????Cursor?myCur?is?select?job?from?emp?for?update; ???????vjob?empa.job%type; ???????rsal?empa.sal%type; ????Begin ???????open?myCur; ???????loop ??????????fetch?myCur?into?vjob; ??????????exit?when?myCur%notFound; ??????????case??(vjob) ?????????????when?'ANALYST'?then??rsal?:=?0.1; ????????????when??'CLERK'?then??rsal?:=?0.2; ?????????????when??'MANAGER'?then??rsal?:=?0.3; ?????????????else ???????????????rsal?:=?0.5; ??????????end?case; ????????update?emp?set?sal?=?sal?+?rsal?where?current?of?myCur; ???????end?loop; ????End; ????/
? ? 例子2:刪除顯示游標記錄
????/*conn?scott/tiger ????Crate?table??empa??Select?*?from?scott.emp; ????*/ ????Declare ??????Cursor?MyCursor??Select???JOB??From??empa??For??Update; ??????vSal???emp.Sal%TYPE; ????Begin ??????Loop ???????Fetch??MyCursor??InTo??vSal; ???????Exit??When??MyCursor%NotFound; ???????If???vSal?<p><strong>什么是帶參數(shù)的顯示游標?</strong></p><p>1、與過程和函數(shù)相似,可以將參數(shù)傳遞給游標并在查詢中使用。</p><p>? 參數(shù)只定義數(shù)據(jù)類型,沒有大小(所有Oracle中的形參只定義數(shù)據(jù)類型,不指定大小)。</p><p>? 與過程不同的是,游標只能接受傳遞的值,而不能返回值。</p><p> ? 可以給參數(shù)設定一個缺省值,當沒有參數(shù)值傳遞給游標時,就使用缺省值。</p><p>? 游標中定義的參數(shù)只是一個占位符,在別處引用該參數(shù)不一定可靠。</p><p>2、使用帶參數(shù)的顯示游標</p>
-
聲明帶參數(shù)的顯示游標:
???CURSOR?游標名??[(parameter[,parameter],...)]????IS???Select語句;
參數(shù)形式:
1,參數(shù)名? ?數(shù)據(jù)類型??
2,參數(shù)名? ?數(shù)據(jù)類型? default? 默認值
? ?例子:
????/*conn?scott/tiger ????Crate?table??empa??Select?*?from?scott.emp; ????*/ ????Declare ??????Cursor?MyCursor(pSal??Number??Default???800)??Select???JOB??From??empa?Where??SAL?>??pSal?; ??????varA??MyCursor%ROWTYPE; ????Begin ??????Loop ???????Fetch??MyCursor??InTo??varA; ???????Exit??When??MyCursor%NotFound; ???????DBMS_OUTPUT.PUT_LINE(MyCursor%RowCount||'????'||varA.empno||'????'||varA.ename||'??'||varA.sal);? ??????End????Loop; ????End;/
推薦教程:《Oracle教程》