更新時(shí)間:2021-03-16 17:22:04 來源:動(dòng)力節(jié)點(diǎn) 瀏覽1222次
在PL/SQL中,針對多行多列的數(shù)據(jù)類型,可以使用游標(biāo)變量。當(dāng)在PL/SQL中執(zhí)行SELECT, INSERT, UPDATE, DELETE語句時(shí),Oracle服務(wù)器會(huì)為這些語句分配相應(yīng)的上下文區(qū)域(Context Area),Oracle使用該上下文區(qū)域解析和處理相應(yīng)的SQL語句。PL/SQL游標(biāo)就是指向該上下文區(qū)域的指針,通過該指針,開發(fā)者可以獲取語句的執(zhí)行狀態(tài),還可以對查詢語句返回的多條記錄進(jìn)行逐條的訪問和處理。
1、PL/SQL游標(biāo)的基本操作
游標(biāo)包括兩種游標(biāo):隱含游標(biāo)和顯式游標(biāo)。隱含游標(biāo)用于處理SELECT INTO和DML語句,而顯式游標(biāo)則專門用于處理SELECT語句返回的多行數(shù)據(jù)。
游標(biāo)的基本操作有:聲明游標(biāo)、打開游標(biāo)、提取游標(biāo)和關(guān)閉游標(biāo)。
下面的代碼塊展示了這四個(gè)基本操作:
DECLARE
????CURSOR c_emp IS SELECT * FROM EMP; --聲明游標(biāo)
????emp_record emp%ROWTYPE;BEGIN
????OPEN c_emp; --打開游標(biāo) ???LOOP
????????FETCH c_emp INTO emp_record; --提取游標(biāo)
????????DBMS_OUTPUT.PUT_LINE('雇員名稱:'||emp_record.ename);
????EXIT WHEN c_emp%NOTFOUND;
????END LOOP;
????CLOSE c_emp; --關(guān)閉游標(biāo)END;/
2、PL/SQL游標(biāo)屬性
游標(biāo)作為一個(gè)臨時(shí)表,可以通過游標(biāo)的屬性來獲取游標(biāo)狀態(tài)。游標(biāo)有4個(gè)常用的屬性:
1)%ISOPEN:用于判斷游標(biāo)是否已經(jīng)打開
2)%FOUND:用于判斷游標(biāo)是否找到記錄
3)%NOTFOUND:與%FOUND相反.
4)%ROWCOUNT:返回到當(dāng)前為止已經(jīng)提取到的實(shí)際行數(shù).
3、參數(shù)化游標(biāo)
參數(shù)化游標(biāo)是指帶有參數(shù)的游標(biāo),在定義了參數(shù)游標(biāo)之后,當(dāng)使用不同的參數(shù)值多次打開游標(biāo)時(shí),可以生成不同的結(jié)果集。參數(shù)化游標(biāo)的聲明語法如下:
CURSOR cursor_name(parameter) IS SELECE ...
Example:參數(shù)化游標(biāo)的使用
DECLARE
????CURSOR emp_cursor(dno NUMBER) IS
????SELECT ename FROM emp WHERE deptno=dno;
????v_ename emp.ename%TYPE;BEGIN
????OPEN emp_cursor(10);
????LOOP
????????FETCH emp_cursor INTO v_ename;
????????EXIT WHEN emp_cursor%NOTFOUND;
????????DBMS_OUTPUT.PUT_LINE(v_ename);
????END LOOP;
????CLOSE emp_cursor;END;/
4、隱式游標(biāo)就是指非PL/SQL程序中定義的,而且是在PL/SQL中使用UPDATE、DELETE或SELECT INTO語句時(shí),Oracle系統(tǒng)自動(dòng)分配的游標(biāo)。隱式游標(biāo)名稱固定為SQL。隱式游標(biāo)無須聲明和打開,使用完后也不用關(guān)閉,所有這一切都由系統(tǒng)自動(dòng)維護(hù)。
Example:SELECT INTO的隱式游標(biāo)
DECLARE
????v_emp emp%ROWTYPE;BEGIN
????SELECT * INTO v_emp FROM emp WHERE empno=7788;
????IF SQL%FOUND THEN
????????DBMS_OUTPUT.PUT_LINE('7788的雇員名稱:'||v_emp.ename);
????END IF;END;/
Example:UPDATE的隱式游標(biāo)
BEGIN
????UPDATE emp SET ename='SCOTT' WHERE empno=7788;
????IF SQL%FOUND THEN
????????DBMS_OUTPUT.PUT_LINE('更新成功!');
????END IF;END;/
5、使用PL/SQL游標(biāo)更新或刪除數(shù)據(jù)
通過使用顯式游標(biāo),不僅可以一行一行地處理SELECT語句的結(jié)果,而且也可以更新或刪除當(dāng)前游標(biāo)行的數(shù)據(jù)。在使用游標(biāo)更新或刪除數(shù)據(jù)時(shí)有兩點(diǎn)需要注意的地方:
聲明游標(biāo)是必須帶有FOR UPDATE子句,如:
CURSOR cursor_name IS SELECT ... FOR UPDATE
在提取了游標(biāo)數(shù)據(jù)之后,為了更新或刪除當(dāng)前游標(biāo)行數(shù)據(jù),必須在UPDATE或DELETE語句中引用WHERE CURRENT OF子句。如:
UPDATE table_name SET column=... WHERE CURRENT OF cursor_name;DELETE table_name WHERE CURRENT OF cursor_name;
Example:使用游標(biāo)更新數(shù)據(jù)
DECLARE
????CURSOR emp_cursor IS SELECT ename,sal FROM emp FOR UPDATE;
????v_ename emp.ename%TYPE;
????v_sal emp.sal%TYPE;BEGIN
????OPEN emp_cursor;
????LOOP
????????FETCH emp_cursor INTO v_ename,v_sal;
????????EXIT WHEN emp_cursor%NOTFOUND;
????????IF v_sal<2000 THEN
????????????UPDATE emp SET sal=sal+100 WHERE CURRENT OF emp_cursor;
????????END IF;
????END LOOP;
????CLOSE emp_cursor;END;/
6、PL/SQL游標(biāo)FOR循環(huán)
當(dāng)使用游標(biāo)FOR循環(huán)時(shí),Oracle會(huì)隱含地打開游標(biāo)、提取游標(biāo)數(shù)據(jù)并關(guān)閉游標(biāo)。
Example:使用游標(biāo)FOR循環(huán)
DECLARE
????CURSOR emp_cursor IS SELECT * FROM emp;
????v_emp emp%ROWTYPE;BEGIN
????FOR v_emp IN emp_cursor LOOP
????????DBMS_OUTPUT.PUT_LINE('第'||emp_cursor%ROWCOUNT||'個(gè)雇員'||v_emp.ename);
????END LOOP;END;/
Example: 在游標(biāo)FOR循環(huán)中直接使用子查詢
DECLARE
????v_emp emp%ROWTYPE;BEGIN
????FOR v_emp IN (SELECT * FROM EMP) LOOP
????????DBMS_OUTPUT.PUT_LINE('編號(hào)'||v_emp.empno||'的雇員名稱:'||v_emp.ename);
????END LOOP;END;/
7、PL/SQL游標(biāo)變量
上面提到的顯式游標(biāo)和隱式游標(biāo)都與固定的查詢語句相關(guān)聯(lián),所以稱之為靜態(tài)游標(biāo)。游標(biāo)變量與靜態(tài)游標(biāo)不同,它是一種動(dòng)態(tài)游標(biāo),在運(yùn)行期間可以與不同的查詢語句相關(guān)聯(lián)。
要聲明游標(biāo)變量,首先得創(chuàng)建一個(gè)游標(biāo)數(shù)據(jù)類型,創(chuàng)建游標(biāo)數(shù)據(jù)類型的語法如下:
TYPE cursor_data_type_name IS REF CURSOR [RETURN return_type];
Example:操作游標(biāo)變量
DECLARE
????TYPE emp_cursor_type IS REF CURSOR RETURN emp%ROWTYPE;
????emp_cursor emp_cursor_type;
????emp_record emp%ROWTYPE;BEGIN
????IF NOT emp_cursor%ISOPEN THEN
????????OPEN emp_cursor FOR SELECT * FROM emp WHERE deptno=10;
????END IF;
????LOOP
????????FETCH emp_cursor INTO emp_record;
????????EXIT WHEN emp_cursor%NOTFOUND;
????????DBMS_OUTPUT.PUT_LINE('雇員名:'||emp_record.ename);
????END LOOP;END;/
本文非常全面的介紹了PL/SQL游標(biāo)的各種操作,幫助我們有效的掌握PL/SQL游標(biāo)的相關(guān)知識(shí)。在本站的PL/SQL教程中還涉及到了其他的PL/SQL的專業(yè)知識(shí),幫助我們開拓新的知識(shí)體系,展開對新知識(shí)和新事物的探究和學(xué)習(xí)。
初級 202925
初級 203221
初級 202629
初級 203743