游標/游標變量


 

 

 

 

 

 

顯式游標

處理顯式游標需要四個 PL/SQL步驟:

定義游標:就是定義一個游標名,以及與其相對應的SELECT 語句

   CURSOR cursor_name IS  select_statement;

 

打開游標:OPEN cursor_name 

 

提取游標:就是檢索結果集合中的數據行,放入指定的輸出變量中

FETCH cursor_name INTO {variable_list | record_variable };

 

關閉游標:當提取和處理完游標結果集合數據后,應及時關閉游標,以釋放該游標所占用的系統資源,

並使該游標的工作區變成無效,不能再使用FETCH 語句取其中數據。

關閉后的游標可以使用OPEN 語句重新打開

CLOSE cursor_name;

例:

 

 1 DECLARE
 2 
 3  v_ename  emp.ename%TYPE;
 4 
 5    v_sal      emp.sal%TYPE;
 6 
 7    CURSOR c_cursor IS SELECT ename, sal FROM emp WHERE rownum<11;
 8 
 9 BEGIN
10 
11 OPEN c_cursor;
12 
13 FETCH c_cursor INTO v_ename, v_sal;
14 
15 WHILE c_cursor %FOUND LOOP
16 
17    DBMS_OUTPUT.PUT_LINE(v_ename||'---'||to_char(v_sal) );
18 
19    FETCH c_cursor INTO v_ename, v_sal;
20 
21 END LOOP;
22 
23 CLOSE c_cursor;
24 
25 END; 

 

參數化游標

例:

DECLARE

v_ename  emp.ename%TYPE;

   v_sal      emp.sal%TYPE;

   CURSOR c_cursor(P_sal emp.sal%type)

          IS SELECT ename, sal FROM emp WHERE sal >= P_sal;

BEGIN

OPEN c_cursor(1000);

FETCH c_cursor INTO v_ename, v_sal;

WHILE c_cursor %FOUND LOOP

   DBMS_OUTPUT.PUT_LINE(v_ename||'---'||to_char(v_sal) );

   FETCH c_cursor INTO v_ename, v_sal;

END LOOP;

CLOSE c_cursor;

END; 

 

游標屬性

%FOUND :布爾型屬性,當最近一次讀記錄時成功返回,則值為TRUE;

%NOTFOUND :布爾型屬性,與%FOUND相反 

%ISOPEN: 布爾型屬性,當游標已打開時返回 TRUE;

%ROWCOUNT:數字型屬性,返回已從游標中讀取的記錄數。

處理隱式游標

例:

 1 DECLARE
 2 
 3 V_deptno emp.deptno%TYPE :=&p_deptno;
 4 
 5 BEGIN
 6 
 7 DELETE FROM emp WHERE deptno=v_deptno;
 8 
 9 IF SQL%NOTFOUND THEN
10 
11 DELETE FROM dept WHERE deptno= 20;
12 
13 END IF;
14 
15 END; 

 

游標檢索循環

例:

 1 DECLARE
 2 
 3    v_empno  emp.empno%TYPE;
 4 
 5    v_sal      emp.sal%TYPE;
 6 
 7    CURSOR c_cursor IS SELECT empno, sal FROM emp; 
 8 
 9     BEGIN
10 
11    OPEN c_cursor;
12 
13    LOOP
14 
15       FETCH c_cursor INTO v_empno, v_sal;
16 
17       EXIT WHEN c_cursor %NOTFOUND; 
18 
19       IF v_sal<=1200 THEN
20 
21             UPDATE emp SET sal=sal+50 WHERE empno=v_empno;
22 
23             DBMS_OUTPUT.PUT_LINE('編碼為'||v_empno||'工資已更新!');
24 
25 END IF;
26 
27 DBMS_OUTPUT.PUT_LINE('記錄數:'|| c_cursor %ROWCOUNT);
28 
29    END LOOP;
30 
31    CLOSE c_cursor;
32 
33 END; 

 

游標的FOR循環

FOR index_variable IN cursor_name[value[, value]…] LOOP

-- 游標數據處理代碼

END LOOP; 

例:

 1 DECLARE
 2 
 3    CURSOR c_sal IS SELECT empno, ename, sal FROM emp ;
 4 
 5 BEGIN
 6 
 7 --隱含打開游標
 8 
 9    FOR v_sal IN c_sal LOOP
10 
11    --隱含執行一個FETCH語句
12 
13    DBMS_OUTPUT.PUT_LINE( to_char(v_sal.empno)||---‘||v_sal.ename||’---‘||to_char(v_sal.sal)) ;
14 
15    --隱含監測c_sal%NOTFOUND
16 
17    END LOOP;
18 
19 --隱含關閉游標
20 
21 END; 

 

SELECT FOR UPDATE 游標

游標修改和刪除操作是指在游標定位下,修改或刪除表中指定的數據行。這時,要求游標查詢語句中必須使用FOR UPDATE選項

SELECT . . . FROM … FOR UPDATE [OF column[, column]…] [NOWAIT]

例:DECLARE 

V_deptno emp.deptno%TYPE :=&p_deptno;

CURSOR emp_cursor IS SELECT empno, sal 

FROM emp WHERE deptno=v_deptno FOR UPDATE NOWAIT;

BEGIN

FOR emp_record IN emp_cursor LOOP

IF emp_record.sal < 1500 THEN

UPDATE emp SET sal=1500 WHERE CURRENT OF emp_cursor;

END IF;

END LOOP;

--COMMIT;

END;

游標變量

與游標一樣,游標變量也是一個指向多行查詢結果集合中當前數據行的指針。但與游標不同的是,游標變量是動態的,而游標是靜態的。游標只能與指定的查詢相連,即固定指向一個查詢的內存處理區域,而游標變量則可與不同的查詢語句相連,它可以指向不同查詢語句的內存處理區域(但不能同時指向多個內存處理區域,在某一時刻只能與一個查詢語句相連),只要這些查詢語句的返回類型兼容即可。

游標變量為一個指針,它屬於參照類型,所以在聲明游標變量類型之前必須先定義游標變量類型。

TYPE ref_type_name IS REF CURSOR [ RETURN return_type] (強[弱]游標變量)

例:聲明兩個強類型定義游標變量和一個弱類型游標變量  

 1 DECLARE
 2 
 3 TYPE deptrecord IS RECORD(
 4 
 5 Deptno dept.deptno%TYPE,
 6 
 7 Dname dept.deptno%TYPE,
 8 
 9 Loc dept.loc%TYPE );
10 
11 TYPE deptcurtype IS REF CURSOR RETURN dept%ROWTYPE;
12 
13 TYPE deptcurtyp1 IS REF CURSOR RETURN deptrecord;
14 
15 TYPE curtype IS REF CURSOR;
16 
17 Dept_c1 deptcurtype;
18 
19 Dept_c2 deptcurtyp1;
20 
21 Cv curtype;

 

打開游標變量 :打開游標變量時使用的是OPEN…FOR 語句

提取游標變量數據 :

關閉游標變量 :

例:強類型參照游標變量類型 

  

 1   DECLARE
 2 
 3 TYPE emp_job_rec IS RECORD(
 4 
 5 Employee_id emp.empno%TYPE,
 6 
 7 Employee_name emp.ename%TYPE,
 8 
 9 Job_title emp.job%TYPE);
10 
11 TYPE emp_job_refcur_type IS REF CURSOR RETURN emp_job_rec;
12 
13 Emp_refcur emp_job_refcur_type ;
14 
15 Emp_job emp_job_rec;
16 
17 BEGIN
18 
19 OPEN emp_refcur FOR 
20 
21 SELECT empno, ename, job FROM emp ORDER BY deptno;
22 
23 FETCH emp_refcur INTO emp_job;
24 
25 WHILE emp_refcur%FOUND LOOP
26 
27 DBMS_OUTPUT.PUT_LINE(emp_job.employee_id||’: ‘||emp_job.employee_name||is a ’||emp_job.job_title);
28 
29 FETCH emp_refcur INTO emp_job;
30 
31 END LOOP;
32 
33 END; 

 

例:弱類型參照游標變量類型 

    

 1 DECLARE
 2 
 3 Type refcur_t IS REF CURSOR;
 4 
 5 Refcur refcur_t;
 6 
 7 TYPE sample_rec_type IS RECORD (
 8 
 9 Id number,
10 
11 Description VARCHAR2 (30) );
12 
13 sample sample_rec_type;
14 
15 selection varchar2(1) := UPPER (SUBSTR (‘&tab’, 1, 1));
16 
17 BEGIN
18 
19 IF selection=’D’ THEN
20 
21    OPEN refcur FOR SELECT deptno, dname FROM dept;
22 
23    DBMS_OUTPUT.PUT_LINE(‘Department data’);
24 
25 ELSIF selection=’E’ THEN
26 
27    OPEN refcur FOR SELECT empno, ename||is a ‘||job FROM emp;
28 
29    DBMS_OUTPUT.PUT_LINE(‘Employee data’);
30 
31 ELSE
32 
33    DBMS_OUTPUT.PUT_LINE(‘Please enter ‘‘D’’ or ‘‘E’’ ’);
34 
35    RETURN;
36 
37 END IF;
38 
39 DBMS_OUTPUT.PUT_LINE(‘----------------------‘);
40 
41 FETCH refcur INTO sample;
42 
43 WHILE refcur%FOUND LOOP
44 
45    DBMS_OUTPUT.PUT_LINE(sample.id||’: ‘||sample.description);
46 
47    FETCH refcur INTO sample;
48 
49 END LOOP;
50 
51 CLOSE refcur;
52 
53     END; 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM