Oracle基础 游标
一、游標(biāo)
游標(biāo)用來處理從數(shù)據(jù)庫中檢索的多行記錄(使用SELECT語句)。利用游標(biāo),程序可以逐個(gè)地處理和遍歷一次檢索返回的整個(gè)記錄集。
?????為了處理SQL語句,Oracle將在內(nèi)存中分配一個(gè)區(qū)域,這就是上下文區(qū)。這個(gè)區(qū)包含了已經(jīng)處理完的行數(shù)、指向被分析語句的指針,整個(gè)區(qū)是查詢語句返回的數(shù)據(jù)行集。游標(biāo)就是指向上下文區(qū)句柄或指針。
?
二、游標(biāo)的分類:
1、靜態(tài)游標(biāo):靜態(tài)游標(biāo)是在編譯時(shí)知道其SELECT語句的游標(biāo)。靜態(tài)游標(biāo)又分為兩種類型,隱式游標(biāo)和顯示游標(biāo)。
2、動(dòng)態(tài)游標(biāo):用戶為游標(biāo)使用的查詢直到運(yùn)行的時(shí)候才能確定,可以使用REF游標(biāo)和游標(biāo)變量滿足這個(gè)要求。為了使用引用游標(biāo),必須聲明游標(biāo)變量。有兩種類型的REF游標(biāo):強(qiáng)類型REF游標(biāo)和弱類型REF游標(biāo)。
?
?
三、顯示游標(biāo)的用法:
顯示游標(biāo)被用于處理返回多行數(shù)據(jù)的SELECT?語句,游標(biāo)名通過CURSOR….IS?語句顯示地賦給SELECT?語句。
? ? ? ?(一)使用步驟;
?????? 1)聲明游標(biāo):CURSOR cursor_name IS select_statement
? ? ? ? 2)為查詢打開游標(biāo):OPEN cursor_name
? ? ? ? 3)取得結(jié)果放入PL/SQL變量中;
? ? ? ? ? ? ? ? ?FETCH cursor_name INTO list_of_variables;
????????????? FETCH cursor_name INTO PL/SQL_record;
? ? ? ? 4)關(guān)閉游標(biāo)。CLOSE cursor_name
注意:在聲明游標(biāo)時(shí),select_statement不能包含INTO子句。當(dāng)使用顯示游標(biāo)時(shí),INTO子句是FETCH語句的一部分。
例:顯示雇員的名稱和薪水
--使用LOOP遍歷游標(biāo) DECLAREv_name emp.ename%TYPE;v_sal emp.sal%TYPE;CURSOR cus_emp ISSELECT ename,sal FROM emp; --聲明游標(biāo) BEGINOPEN cus_emp; --打開游標(biāo) LOOP FETCH cus_emp INTO v_name,v_sal; --提取游標(biāo)EXIT WHEN cus_emp%NOTFOUND;dbms_output.put_line('第'||cus_emp%ROWCOUNT||'個(gè)用戶: name:'||v_name||' sal:'||v_sal);END LOOP;CLOSE cus_emp; --關(guān)閉游標(biāo) END;顯示游標(biāo)的屬性:
%FOUND:只有在DML語句影響一行或者多行是,則返回TRUE;
%NOTFOUND:沒有影響任何行,則返回TRUE。
%ROWCOUNT:返回DML語句影響的行數(shù),沒有影響則返回0;
%ISOPEN:返回游標(biāo)是否打開,在執(zhí)行SQL之后,Oracle自動(dòng)關(guān)閉SQL游標(biāo),所以隱式游標(biāo)的%isopen屬性始終未false;
?
另一種方式:
--使用for來簡化游標(biāo)遍歷 DECLARECURSOR cus_emp ISSELECT ename,sal FROM emp; BEGINFOR record_emp IN cus_empLOOP dbms_output.put_line('第'||cus_emp%ROWCOUNT||'個(gè)用戶: name:'||record_emp.ename||' sal:'||record_emp.sal);END LOOP; END;record_emp是plsql聲明的的記錄變量,此變量的屬性為聲明為%ROWTYPE類型,作用域在FOR循環(huán)之內(nèi),即在FOR循環(huán)外就不能訪問了。
循環(huán)游標(biāo)的特性:
(1)從游標(biāo)中提取了所有記錄之后自動(dòng)終止。
(2)提取和處理游標(biāo)中的每一條記錄。
(3)如果在提取記錄之后%NOTFOUND屬性返回TRUE,則終止循環(huán)。如果未返回任何行,則不進(jìn)入循環(huán)。
?
游標(biāo)案例:
--給員工加薪,按員工入職時(shí)間進(jìn)行加薪,每年加100,1000封頂 DECLAREv_date emp.hiredate%TYPE;v_empno emp.empno%TYPE;v_money NUMBER;CURSOR cur_emp ISSELECT empno,hiredate FROM emp; BEGINOPEN cur_emp;LOOPFETCH cur_emp INTO v_empno,v_date;EXIT WHEN cur_emp%NOTFOUND;v_money := 100*(1990-to_char(v_date,'yyyy'));IF v_money<1000 THENUPDATE emp SET sal=sal+v_money WHERE empno=v_empno;ELSEUPDATE emp SET sal=sal+1000 WHERE empno=v_empno;END IF; END LOOP; END;?
四、隱式游標(biāo):
所有的隱式游標(biāo)都被假設(shè)為只返回一條記錄。
使用隱式游標(biāo)時(shí),用戶無需進(jìn)行聲明、打開及關(guān)閉。PL/SQL隱含地打開、處理,然后關(guān)掉游標(biāo)。多條sql語句 隱式游標(biāo)SQL永遠(yuǎn)指的是最后一條sql語句的結(jié)果,主要使用在update 和 delete語句上。
隱式游標(biāo)的四個(gè)屬性:
?
| 屬性 | 說明 |
| ?SQL%rowcount | ?影響的記錄的行數(shù)整數(shù)(用來判斷插入,更新修改是否成功,必須在comit之前,否則提交后結(jié)果為0.) |
| ?SQL%found | ?影響到了記錄 true() |
| ?SQL%notfound | ?沒有影響到記錄 true |
| ?SQL%isopen | ?是否打開 布爾值 永遠(yuǎn)是false |
例如:
?
上述游標(biāo)自動(dòng)打開,并把相關(guān)值賦給對(duì)應(yīng)變量,然后關(guān)閉。執(zhí)行完后,PL/SQL變量rowemp.ename,rowemp.sal中已經(jīng)有了值。
五:動(dòng)態(tài)游標(biāo)
靜態(tài)游標(biāo)是在聲明就已經(jīng)確定查詢語句,如果用戶需要在運(yùn)行時(shí)動(dòng)態(tài)決定游標(biāo)執(zhí)行的查詢,就需要使用動(dòng)態(tài)游標(biāo)(REF游標(biāo))。
動(dòng)態(tài)游標(biāo)分為兩類:強(qiáng)類型游標(biāo)和弱類型游標(biāo)。
動(dòng)態(tài)游標(biāo)使用步驟:
1、聲明動(dòng)態(tài)游標(biāo)類型;
2、打開游標(biāo),指定游標(biāo)查詢;
3、提取游標(biāo)。
4、關(guān)閉游標(biāo)。
例:
強(qiáng)類型游標(biāo),使用return聲明的游標(biāo)為強(qiáng)類型游標(biāo)。在對(duì)游標(biāo)進(jìn)行綁定查詢只能綁定游標(biāo)返回的類型rowtype。
--強(qiáng)類型的動(dòng)態(tài)游標(biāo),查詢emp表中的數(shù)據(jù) DECLARETYPE ref_cur IS REF CURSOR --聲明游標(biāo)類型RETURN emp%ROWTYPE; --帶返回值的為強(qiáng)類型動(dòng)態(tài)游標(biāo)refcur_emp ref_cur; --游標(biāo)類型對(duì)象v_emp emp%ROWTYPE; BEGINOPEN refcur_emp FOR --將游標(biāo)綁定到一個(gè)查詢語句,因?yàn)槁暶鞯氖菑?qiáng)類型,所以只能綁定emp;SELECT * FROM emp; LOOPFETCH refcur_emp INTO v_emp; --提取游標(biāo)內(nèi)容EXIT WHEN refcur_emp%NOTFOUND;dbms_output.put_line(refcur_emp%Rowcount||'、name:'||v_emp.ename||' sal:'||v_emp.sal);END LOOP;CLOSE refcur_emp; END;
弱類型游標(biāo):可以用來綁定多個(gè)查詢結(jié)果。
例:
--弱類型游標(biāo) DECLARETYPE refcur IS REF CURSOR; --未定義返回類型為弱類型游標(biāo) rc refcur;v_name emp.ename%TYPE;v_deptname dept.dname%TYPE; BEGINOPEN rc FOR SELECT ename,dname FROM emp e,dept d WHERE e.deptno = d.deptno; --綁定查詢 LOOPFETCH rc INTO v_name,v_deptname; EXIT WHEN rc%NOTFOUND;dbms_output.put_line('name:'||v_name||' deptname:'||v_deptname);END LOOP;CLOSE rc; END;?
例:
--根據(jù)輸入的內(nèi)容綁定游標(biāo) DECLARE TYPE refcur IS REF CURSOR;rc refcur;v_tablename VARCHAR2(10) := '&tab';v_id NUMBER;v_name VARCHAR2(20); BEGINIF(v_tablename = 'e') THENOPEN rc FOR SELECT e.empno,e.ename INTO v_id,v_name FROM emp e;dbms_output.put_line('=========員工信息=============');Elsif(v_tablename = 'd') THENOPEN rc FOR SELECT d.deptno,d.dname INTO v_id,v_name FROM dept d;dbms_output.put_line('=========部門信息=============');ELSEdbms_output.put_line('輸入錯(cuò)誤,請(qǐng)輸入e或者d!');RETURN;END IF; LOOP FETCH rc INTO v_id,v_name;dbms_output.put_line('#'||rc%Rowcount||' id:'||v_id||' name:'||v_name);EXIT WHEN rc%NOTFOUND;END LOOP; END;?
總結(jié)
以上是生活随笔為你收集整理的Oracle基础 游标的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第一次接触终极事务处理——Hekaton
- 下一篇: 使用双栈实现一个队列