pl/sql--帶引數遊標的使用
一般遊標中,SELECT語句都沒有WHERE子句,或者用WHERE子句指定了一個固定的條件,這樣每次都查詢同樣的資料。在更多的情況下,可能要根據實際情況查詢不同的資料。為了通過遊標對資料進行更加靈活的處理,可以為遊標定義引數,這些引數可以用在WHERE子句中。在開啟遊標時,指定實際的引數值,這樣遊標在每次開啟時,可以根據不同的實際引數值,返回所需的不同資料。
定義帶引數的遊標的語法格式為:
DECLARE
CURSOR 遊標名(引數1, 引數2, ...)
IS
SELECT語句;
其中引數的定義方法與子程式中的引數定義完全相同,可以指定預設值,指定引數傳遞模式。預設的引數傳遞模式為IN,如果要使用OUT或者“IN OUT”模式,就需要明確指定。由於遊標一般不需要通過引數向呼叫者傳遞資料,所以OUT模式在遊標中沒有什麼實際用處。
在用OPEN命令開啟遊標時,要向遊標提供實際引數,遊標根據提供的引數值,查詢符合條件的資料。開啟遊標的語法格式為:
OPEN遊標名(實際引數1, 實際引數2...);
例:
DECLARE CURSOR cur_6(d_no IN emp.deptno%type, min_sal IN emp.sal%type := 1000) IS SELECT ename, sal, hiredate FROM emp WHERE deptno = d_no and sal >= min_sal; e cur_6%rowtype;BEGIN if not cur_6%ISOPEN then --如果遊標沒有開啟,則開啟它 open cur_6(20, 2000); END if; fetch cur_6 INTO e; --取出第一行資料 while cur_6%found loop dbms_output.put_line('姓名:' || e.ename || '工資:' || e.sal || ' 工作時間:' || e.hiredate); fetch cur_6 INTO e; END loop; dbms_output.put_line('員工總數:' || cur_6%rowcount); --獲取的總行數 close cur_6; --關閉遊標 END;
這個塊的執行結果為:
姓名:JONES 工資:2975 工作時間:02-4月-81 姓名:SCOTT 工資:3000 工作時間:19-4月-87 姓名:FORD 工資:3000 工作時間:03-12月-81 員工總數:3
在這個例子中,用傳統的迴圈方法處理遊標。首先定義了一個帶引數的遊標,引數d_no表示部門編號,min_sal表示最低工資,兩個引數的傳遞模式都是IN。遊標的功能是查詢屬於指定部門並且工資不低於指定值的所有員工。
在開啟遊標時,指定了兩個實際引數20和2000,這樣,檢索出來的資料就是屬於部門20,並且工資不低於2000的所有員工。如果再次以“open cur_6(10,3000)”的形式開啟遊標,那麼檢索到的資料就是屬於部門10,並且工資不低於3000的員工。由此可見,帶引數的遊標在查詢資料時更加靈活。
如果要用FOR迴圈處理遊標中的資料,可以按照同樣的方法定義遊標。由於沒有使用OPEN命令開啟遊標,所以實際引數在FOR語句中指定。這時FOR語句的格式為:
FOR 變數 IN 遊標(實際引數1, 實際引數2...) LOOP ... END LOOP;
在迴圈開始執行時,遊標自動開啟,並根據指定的實際引數查詢資料。例如,用FOR迴圈處理帶引數的遊標,對上面的PL/SQL塊進行修改,程式碼如下:
DECLARE
CURSOR cur_7(d_no emp.deptno%type, min_sal emp.sal%type) IS
SELECT ename, sal, hiredate
FROM emp
WHERE deptno = d_no
and sal >= min_sal;
e_count integer := 0;
BEGIN
FOR e IN cur_7(10, 3000) LOOP
dbms_output.put_line('姓名:' || e.ename || ' 工資:
' || e.sal || ' 工作時間:' || e.hiredate);
e_counte_count := e_count + 1;
END LOOP;
dbms_output.put_line('員工總數:' || e_count);
END;
執行結果為:
姓名:KING 工資:5000 工作時間:17-11月-81
員工總數:1