一、遊標分為靜態遊標和動態遊標,靜態遊標又分為:顯示遊標和隱式遊標,動態遊標分為:強類型和弱類型。
二、靜態遊標
1、顯示遊標
顯示遊標語法:
1)定義遊標
cursor 遊標名 is
2)打開遊標
open 又表明
3)提取遊標
fetch 遊標名 into 變量名
4)關閉遊標
close 遊標名
舉例一:
--檢索EMP表中的所有JOB為MANAGER的僱員信息
DECLARE
/*聲明遊標、(遊標輸入參數變量為VAR_JOB)可選項*/
CURSOR CUR_EMP(VAR_JOB IN VARCHAR2:='SALESMAN') IS
/*遊標所使用的查詢語句*/
SELECT EMPNO, ENAME, SAL FROM EMP WHERE JOB = VAR_JOB;
EMP_ROW EMP%ROWTYPE;
BEGIN
/*打開遊標,指定輸入參數值為MANAGER*/
OPEN CUR_EMP('MANAGER');
/*將遊標指向結果集第一行數據並存入RECORD記錄變量*/
FETCH CUR_EMP
INTO EMP_ROW;
/*如果遊標有數據就循環*/
WHILE CUR_EMP%FOUND LOOP
DBMS_OUTPUT.PUT_LINE('僱員編號:' || EMP_ROW.VAR_EMPNO || ' 僱員姓名:' ||
EMP_ROW.VAR_ENAME || ' 僱員薪水:' || EMP_ROW.VAR_SAL);
/*將遊標指向結果集下一條數據*/
FETCH CUR_EMP
INTO EMP_ROW;
END LOOP;
/*關閉遊標*/
CLOSE CUR_EMP;
END;
舉例二:
--檢索EMP表中的所有JOB為MANAGER的僱員信息
DECLARE
/*聲明遊標、(遊標輸入參數變量為VAR_JOB)可選項*/
CURSOR CUR_EMP(VAR_JOB IN VARCHAR2:='SALESMAN') IS
/*遊標所使用的查詢語句*/
SELECT EMPNO, ENAME, SAL FROM EMP WHERE JOB = VAR_JOB;
/*聲明一個RECORD類型的記錄變量*/
TYPE RECORD_EMP IS RECORD(
VAR_EMPNO EMP.EMPNO%TYPE,
VAR_ENAME EMP.ENAME%TYPE,
VAR_SAL EMP.SAL%TYPE);
EMP_ROW RECORD_EMP;
BEGIN
/*打開遊標,指定輸入參數值為MANAGER*/
OPEN CUR_EMP('MANAGER');
/*將遊標指向結果集第一行數據並存入RECORD記錄變量*/
FETCH CUR_EMP
INTO EMP_ROW;
/*如果遊標有數據就循環*/
WHILE CUR_EMP%FOUND LOOP
DBMS_OUTPUT.PUT_LINE('僱員編號:' || EMP_ROW.VAR_EMPNO || ' 僱員姓名:' ||
EMP_ROW.VAR_ENAME || ' 僱員薪水:' || EMP_ROW.VAR_SAL);
/*將遊標指向結果集下一條數據*/
FETCH CUR_EMP
INTO EMP_ROW;
END LOOP;
/*關閉遊標*/
CLOSE CUR_EMP;
END;
顯示遊標有一下屬性:
2、隱式遊標
當用戶在PL/SQL中使用數據操縱語言(DML)時,Oracle預先定義一個名為SQL的隱士遊標,通過檢查隱式遊標的屬性可以獲取與最近執行的SQL語句相關的信息。
例:
DECLARE
BEGIN
UPDATE EMP SET SAL = SAL + 100 WHERE JOB = 'SALESMAN';
IF SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('沒有符合條件的僱員');
ELSE
DBMS_OUTPUT.PUT_LINE('上調了:' || SQL%ROWCOUNT || '個僱員的工資');
END IF;
END;
隱式遊標屬性:
三、動態遊標
動態遊標分為:為強類型和弱類型倆種。在定義遊標變量類型時,如果指定了遊標變量的返回值類型,那麼就是強類型,如果沒指定,就是弱類型。並且一旦指定了返回值類型,在打開遊標時,綁定的查詢結果的返回集一定是return中定義的類型。
動態遊標用法:
1)聲明遊標變量
2)打開遊標
3)提取遊標數據
4)關閉遊標
例:
--弱類型
--將薪水低於3000的僱員薪水增加500,增加後最高不超過3000
DECLARE
TYPE REF_CURSOR_TYPE IS REF CURSOR; --聲明一個弱類型的動態遊標類型
REF_CURSOR REF_CURSOR_TYPE; --定義一個遊標為聲明的弱類型遊標
V_SAL EMP.SAL%TYPE;--聲明一個變量用來接收僱員薪水
V_EMPNO EMP.EMPNO%TYPE;--聲明一個變量用來接收僱員編號
BEGIN
OPEN REF_CURSOR FOR
SELECT SAL, EMPNO FROM EMP;--打開遊標並指定使用的SQL語句
LOOP
FETCH REF_CURSOR
INTO V_SAL, V_EMPNO;--將遊標指向一行數據並給變量賦值
EXIT WHEN REF_CURSOR%NOTFOUND;--當遊標無數據時退出
IF V_SAL < 3000 THEN--薪水低於3000進入IF,這個IF最後會執行更新SQL
IF V_SAL >= 2500 THEN--薪水低於3000又大於2500進入這個IF
V_SAL := 3000;
ELSE
V_SAL := V_SAL + 500;
END IF;--結束一個IF,一個IF對應一個END IF;
UPDATE EMP SET SAL = V_SAL WHERE EMPNO = V_EMPNO;--更新僱員薪水
END IF;--結束最外層IF
END LOOP;--結束LOOP循環
CLOSE REF_CURSOR;--關閉遊標
END;
--強類型
--查詢所有僱員姓名
DECLARE
TYPE EMP_REF_CURSOR IS REF CURSOR RETURN EMP%ROWTYPE;--聲明一個強類型(指定返回類型)的動態遊標
REF_CURSOR EMP_REF_CURSOR;--定義一個聲明的強類型遊標
V_EMP_RECORD EMP%ROWTYPE;--定義一個接收變量
BEGIN
OPEN REF_CURSOR FOR
SELECT * FROM EMP;
LOOP
FETCH REF_CURSOR
INTO V_EMP_RECORD;
EXIT WHEN REF_CURSOR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(V_EMP_RECORD.ENAME);
END LOOP;
CLOSE REF_CURSOR;
END;