1. 程式人生 > >pl/sql--帶引數遊標的使用

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