遊標是映射在結果集中一行資料上的位置實體,有了遊標,使用者就可以訪問結果集中的任意一行資料了,將遊標放置到某行後,即可對該行資料進行操作,例如提取當前行的資料等。
oracle 遊標有4個屬性:%ISOPEN,%FOUND,%NOTFOUND,%ROWCOUNT。
%ISOPEN判斷遊標是否被開啟,如果開啟%ISOPEN等於true,否則等於false;
%FOUND %NOTFOUND判斷遊標所在的行是否有效,如果有效,則%FOUNDD等於true,否則等於false;
%ROWCOUNT返回當前位置為止遊標讀取的記錄行數。oracle 遊標有4個屬性:%ISOPEN,%FOUND,%NOTFOUND,%ROWCOUNT。
%ISOPEN判斷遊標是否被開啟,如果開啟%ISOPEN等於true,否則等於false;
%FOUND %NOTFOUND判斷遊標所在的行是否有效,如果有效,則%FOUNDD等於true,否則等於false;
%ROWCOUNT返回當前位置為止遊標讀取的記錄行數。
----------------------------------------------------------------------------------------------------------------------------
遊標分為顯式遊標和隱式遊標。
當使用顯式遊標時,需要在定義顯式遊標時指定相應的select語句,這種顯式遊標成為靜態資料指標。例如:
CURSOR mycur(vartype number) is
select emp_no,emp_zc from cus_emp_basic
where com_no = vartype;
當使用遊標變數REF CURSOR時,在定義遊標變數時不需要指定selelct語句,而是在開啟遊標時指定select語句,從而實現動態資料指標操作。例如:
DECLARE
TYPE c1 IS REF CURSOR;
emp_cursor c1;
v_ename emp.ename%TYPE;
v_sal emp.sal%TYPE;
BEGIN
OPEN emp_cursor FOR
select ename,sal FROM emp where deptno = 10;
LOOP
fetch emp_cursor INTO v_ename,v_sal;
EXIT WHEN emp_cursor%NOTFOUND;
dbms_output.put_line(v_name);
END LOOP;
CLOSE emp_cursor;
END;
-----------------------------------------------------------------------------------------------------------------------------
FOR UPDATE子句用於在遊標結果集資料上加行共用鎖定,以防止其他使用者在相應行上執行DML操作;當SELECT語句引用到多張表時,使用OF子句可以確定哪些表要加鎖,如果沒有OF子句,則會在SELECT語句所引用的全部表上加鎖;NOWAIT子句用於指定不等待鎖。在提取了遊標資料之後,為了更新或刪除當前遊標行資料,必須在UPDATE或DELETE語句中引用WHERE CURRENT OF子句。
使用顯式遊標更新資料:
DECLARE
CURSOR emp_cursor IS
SELCET ename, sal FROM emp FOR UPDATE;
v_ename emp.ename%TYPE;
v_oldsal emp.sal%TYPE;
BEGIN
OPEN emp_cursor;
LOOP
FETCH emp_cursor INTO v_ename, v_oldsal;
EXIT WHEN emp_cursor%NOTFOUND;
IF v_oldsal<2000 THEN
UPDATE emp SET sal=sal+100 WHERE CURRENT OF emp_cursor;
END IF;
END LOOP;
CLOSE emp_cursor;
END;
--------------------------------------------------------------------------------------------------------------------------------
CURSOR運算式用於返回嵌套遊標,例:
DECLARE
TYPE refcursor IS REF CURSOR;
CURSOR dept_cursor(no NUMBER) IS
SELECT a.dname, CURSOR(SELECT ename, sal FROM emp
WHERE deptno=a.deptno)
FROM dept a WHERE a.deptno=no;
empcur refcursor;
v_dname dept.dname%TYPE;
v_ename emp.ename%TYPE;
v_sal emp.sal%TYPE;
BEGIN
OPEN dept_cursor(&no);
LOOP
FETCH dept_cursor INTO v_dname, empcur;
EXIT WHEN dept_cursor%NOTFOUND;
dbms_output.put_line('部門名:'||v_dname);
LOOP
FETCH empcur INTO v_ename, v_sal;
EXIT WHEN empcur%NOTFOUND;
dbms_output.put_line('僱員名:'||v_ename||',工資:'||v_sal);
END LOOP;
CLOSE dept_cursor;
END;