码迷,mamicode.com
首页 > 其他好文 > 详细

游标/游标变量

时间:2017-07-26 19:26:19      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:定位   wait   集合   val   title   set   sop   esc   turn   

 

 

 

 

 

 

显式游标

处理显式游标需要四个 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; 

 

游标/游标变量

标签:定位   wait   集合   val   title   set   sop   esc   turn   

原文地址:http://www.cnblogs.com/-maji/p/7241317.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!