/*遊標
目的:爲了處理SELECT語句返回多行數據
使用步驟:
1、定義遊標
CURSOR cursor_name IS select_statement
2、打開遊標
OPEN cursor_name
3、提取數據
FETCH cursor_name INTO variable1,... --提取一行數據
或
FETCH cursor_name INTO BULK COLLECT collect1,... --提取多行數據
4、關閉遊標
CLOSE cursor_name
顯示遊標屬性:
使用方法:cursor_name%遊標屬性
常用遊標屬性:
%ISOPEN
%FOUND
%NOT FOUND
%ROWCOUNT
*/
DECLARE
CURSOR emp_cursor
IS
SELECT ename,sal FROM emp WHERE deptno=20;
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;
dbms_output.put_line('姓名:' || v_ename || ',薪水:' || v_sal);
END LOOP;
CLOSE emp_cursor;
END;
/*參數遊標
CURSOR cursor_name (parameter_name datatype)
IS
select_statement
*/
DECLARE
CURSOR getUser_cursor(cno NUMBER)
IS
SELECT ename,sal FROM emp WHERE deptno=cno;
v_ename emp.ename%TYPE;
v_sal emp.sal%TYPE;
BEGIN
IF NOT getUser_cursor%ISOPEN THEN
OPEN getUser_cursor(&NO);
END IF;
LOOP
FETCH getUser_cursor INTO v_ename,v_sal;
EXIT WHEN getUser_cursor%NOTFOUND;
dbms_output.put_line('姓名:' || v_ename || ',薪水:' || v_sal);
END LOOP;
CLOSE getUser_cursor;
END;
/*使用遊標更新或刪除數據
CURSOR cursor_name (parameter_name datatype) IS select_statement
FOR UPDATE [OF column_reference] [NOWAIT];
FOR UPDATE子句用於在遊標結果集數據上加共享鎖
[OF column_reference]對指定列加鎖,如沒有[OF column_reference]則全表加鎖
[NOWAIT]指立即加鎖
注意:在提取了遊標數據之後,爲了更新或刪除當前遊標行數據,必須在UPDATE或DELETE語句中
引用WHERE CURRENT OF子句,語法如下:
UPDATE table_name SET column_name=... WHERE CURRENT OF cursor_name;
DELETE FROM table_name WHERE CURRENT OF cursor_name;
*/
DECLARE
CURSOR addSal_cursor
IS
SELECT ename,sal FROM emp FOR UPDATE OF sal; --在sal列上加上共享鎖
v_ename emp.ename%TYPE;
v_sal emp.sal%TYPE;
BEGIN
OPEN addSal_cursor;
LOOP
FETCH addSal_cursor INTO v_ename,v_sal;
EXIT WHEN addSal_cursor%NOTFOUND;
IF v_sal<2500 THEN
UPDATE emp SET sal=sal+250 WHERE CURRENT OF addSal_cursor;
END IF;
END LOOP;
CLOSE addSal_cursor;
END;
SELECT * FROM emp;
/*遊標的FOR循環
FOR record_name IN cursor_name LOOP
statement1;
...
END LOOP;
注意:使用遊標的FOR循環時,不要顯示的打開和關閉遊標
*/
DECLARE
CURSOR showEmp_cursor
IS
SELECT ename FROM emp WHERE deptno=&NO;
BEGIN
FOR emp_name IN showEmp_cursor
LOOP
dbms_output.put_line('第' || showEmp_cursor%ROWCOUNT || '個員工' || emp_name.ename);
END LOOP;
END;
/*在使用遊標循環時可以直接在遊標FOR循環中使用子查詢*/
BEGIN
FOR emp_name IN (SELECT ename FROM emp WHERE deptno=&NO)
LOOP
dbms_output.put_line('員工:' || emp_name.ename);
END LOOP;
END;