收藏 分享(赏)

PLSQL中的游标.ppt

上传人:依依 文档编号:1123496 上传时间:2018-06-13 格式:PPT 页数:36 大小:408.50KB
下载 相关 举报
PLSQL中的游标.ppt_第1页
第1页 / 共36页
PLSQL中的游标.ppt_第2页
第2页 / 共36页
PLSQL中的游标.ppt_第3页
第3页 / 共36页
PLSQL中的游标.ppt_第4页
第4页 / 共36页
PLSQL中的游标.ppt_第5页
第5页 / 共36页
点击查看更多>>
资源描述

1、PL/SQL中的游标,游标的概念,在 PL/SQL 程序中,对于处理多行记录的事务经常使用游标来实现。 为了处理 SQL 语句,ORACLE 必须分配一片叫上下文( context area )的区域来处理所必需的信息,其中包括要处理的行的数目,一个指向语句被分析以后的表示形式的指针以及查询的活动集(active set)。游标是一个指向上下文的句柄( handle)或指针。通过游标,PL/SQL可以控制上下文区和处理语句时上下文区会发生些什么事情。,游标的概念,对于不同的SQL语句,游标的使用情况不同:,显式游标,处理显式游标需要四个 PL/SQL步骤:,定义游标:就是定义一个游标名,以及与

2、其相对应的SELECT 语句 , 其一般形式为: CURSOR cursor_name IS select_statement;,其中:游标声明部分是唯一可以出现在模块声明部分的步骤,其他三个步骤都在执行或异常处理部分中游标名是标识符,所以也有作用域,并且必须在使用前进行说明任何SELECT语句都是合法的,但是SELECT INTO语句是非法的在声明部分的末尾声明游标,显式游标,处理显式游标需要四个 PL/SQL步骤:,打开游标:就是执行游标所对应的SELECT语句,将其查询结果放入工作区,并且指针指向工作区的首部,标识游标结果集合。,其中:PL/SQL 程序不能用OPEN 语句重复打开同一个

3、游标,OPEN cursor_name,显式游标,处理显式游标需要四个 PL/SQL步骤:,提取游标:就是检索结果集合中的数据行,放入指定的输出变量中。,FETCH cursor_name INTO variable_list | record_variable ;,显式游标,处理显式游标需要四个 PL/SQL步骤:,关闭游标:当提取和处理完游标结果集合数据后,应及时关闭游标,以释放该游标所占用的系统资源,并使该游标的工作区变成无效,不能再使用FETCH 语句取其中数据。关闭后的游标可以使用OPEN 语句重新打开。,CLOSE cursor_name;,显式游标,例:查询前10名员工的信息。

4、DECLARE v_ename emp.ename%TYPE; v_sal emp.sal%TYPE; CURSOR c_cursor IS SELECT ename, sal FROM emp WHERE rownum= P_sal;BEGINOPEN 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;CL

5、OSE c_cursor;END;,游标属性,游标属性,DECLATECURSOR C_cursor is BEGINOPEN C_cursorFETCH C_cursor INTO FETCH C_cursor INTO FETCH C_cursor INTO CLOSE C_cursorEND;,%FOUND返回错误,%FOUND为NULL,%FOUND为TRUE,%FOUND为TRUE,%FOUND返回错误,%FOUND为FALSE,游标属性,DECLATECURSOR C_cursor is BEGINOPEN C_cursorFETCH C_cursor INTO FETCH C_c

6、ursor INTO FETCH C_cursor INTO CLOSE C_cursorEND;,%NOTFOUND返回错误,%NOTFOUND为NULL,%NOTFOUND为FALSE,%NOTFOUND为FALSE,%NOTFOUND返回错误,%NOTFOUND为TRUE,游标属性,DECLATECURSOR C_cursor is BEGINOPEN C_cursorFETCH C_cursor INTO FETCH C_cursor INTO FETCH C_cursor INTO CLOSE C_cursorEND;,%ISOPEN为FALSE,%ISOPEN为TRUE,%ISOP

7、EN为TRUE,%ISOPEN为TRUE,%ISOPEN为FALSE,%ISOPEN为TRUE,游标属性,DECLATECURSOR C_cursor is BEGINOPEN C_cursorFETCH C_cursor INTO FETCH C_cursor INTO FETCH C_cursor INTO CLOSE C_cursorEND;,%ROWCOUNT返回错误,%ROWCOUNT为0,%ROWCOUNT为1,%ROWCOUNT为2,%ROWCOUNT返回错误,%ROWCOUNT为2,练习:给工资低于1200 的员工增加工资50。,处理隐式游标,显式游标主要是用于对查询语句的处理

8、,尤其是在查询结果为多条记录的情况下;而对于非查询语句,如修改、删除操作,则由ORACLE 系统自动地为这些操作设置游标并创建其工作区,这些由系统隐含创建的游标称为隐式游标,隐式游标的名字为SQL,这是由ORACLE 系统定义的。对于隐式游标的操作,如定义、打开、取值及关闭操作,都由ORACLE 系统自动地完成,无需用户进行处理。用户只能通过隐式游标的相关属性,来完成相应的操作。在隐式游标的工作区中,所存放的数据是与用户自定义的显示游标无关的、最新处理的一条SQL 语句所包含的数据。INSERT, UPDATE, DELETE, SELECT INTO语句中不必明确定义游标,隐式游标属性,处理

9、隐式游标,例:删除EMP 表中20号部门的所有员工,如果该部门中已没有员工可删除,则在DEPT 表中删除该部门 DECLAREV_deptno emp.deptno%TYPE :=20;BEGINDELETE FROM emp WHERE deptno=v_deptno;IF SQL%NOTFOUND THENDELETE FROM dept WHERE deptno= 20;END IF;END;,游标检索循环,例:DECLARE v_empno emp.empno%TYPE; v_sal emp.sal%TYPE; CURSOR c_cursor IS SELECT empno, sal

10、FROM emp; BEGIN OPEN c_cursor; LOOP FETCH c_cursor INTO v_empno, v_sal; EXIT WHEN c_cursor %NOTFOUND; IF v_sal=1200 THEN UPDATE emp SET sal=sal+50 WHERE empno=v_empno; DBMS_OUTPUT.PUT_LINE(编码为|v_empno|工资已更新!); END IF; DBMS_OUTPUT.PUT_LINE(记录数:| c_cursor %ROWCOUNT); END LOOP; CLOSE c_cursor;END;,游标的F

11、OR循环,PL/SQL语言提供了游标FOR循环语句,自动执行游标的OPEN、FETCH、CLOSE语句和循环语句的功能;当进入循环时,游标FOR循环语句自动打开游标,并提取第一行游标数据,当程序处理完当前所提取的数据而进入下一次循环时,游标FOR循环语句自动提取下一行数据供程序处理,当提取完结果集合中的所有数据行后结束循环,并自动关闭游标。,FOR index_variable IN cursor_namevalue, value LOOP- 游标数据处理代码END LOOP;,游标的FOR循环,其中:index_variable为游标FOR 循环语句隐含声明的索引变量,该变量为记录变量,其结

12、构与游标查询语句返回的结构集合的结构相同。在程序中可以通过引用该索引记录变量元素来读取所提取的游标数据,index_variable中各元素的名称与游标查询语句选择列表中所制定的列名相同。如果在游标查询语句的选择列表中存在计算列,则必须为这些计算列指定别名后才能通过游标FOR 循环语句中的索引变量来访问这些列数据。,游标的FOR循环,例:DECLARE CURSOR c_sal IS SELECT empno, ename, sal FROM emp ;BEGIN-隐含打开游标 FOR v_sal IN c_sal LOOP -隐含执行一个FETCH语句-隐含监测c_sal%NOTFOUND

13、DBMS_OUTPUT.PUT_LINE( to_char(v_sal.empno)|-|v_sal.ename|-|to_char(v_sal.sal) ;END LOOP;-隐含关闭游标END;,游标的FOR循环,例:DECLARECURSOR c_cursor(dept_no NUMBER DEFAULT 10) IS SELECT dname, loc FROM dept WHERE deptno = dept_no;BEGINDBMS_OUTPUT.PUT_LINE(dept_no参数值为30:);FOR c1_rec IN c_cursor (30) LOOPDBMS_OUTPUT

14、.PUT_LINE(c1_rec.dname|-|c1_rec.loc);END LOOP;DBMS_OUTPUT.PUT_LINE(CHR(10)|使用默认的dept_no参数值10:);FOR c1_rec IN c_cursor LOOPDBMS_OUTPUT.PUT_LINE(c1_rec.dname|-|c1_rec.loc);END LOOP;END;,NO_DATA_FOUND 和 %NOTFOUND的区别,SELECT INTO 语句触发 NO_DATA_FOUND;当一个显式游标的WHERE子句未找到时触发%NOTFOUND;当UPDATE或DELETE 语句的WHERE 子

15、句未找到时触发 SQL%NOTFOUND;在提取循环中要用 %NOTFOUND 或%FOUND 来确定循环的退出条件,不要用 NO_DATA_FOUND.,SELECT FOR UPDATE 游标,游标修改和删除操作是指在游标定位下,修改或删除表中指定的数据行。这时,要求游标查询语句中必须使用FOR UPDATE选项,以便在打开游标时锁定游标结果集合在表中对应数据行的所有列和部分列。为了对正在处理(查询)的行不被另外的用户改动,ORACLE 提供一个 FOR UPDATE 子句来对所选择的行进行锁住。该需求迫使ORACLE锁定游标结果集合的行,可以防止其他事务处理更新或删除相同的行,直到您的事

16、务处理提交或回退为止。,SELECT FOR UPDATE 游标,一般形式为:,注意:如果另一个会话已对活动集中的行加了锁,那么SELECT FOR UPDATE操作一直等待到其它的会话释放这些锁后才继续自己的操作,对于这种情况,当加上NOWAIT子句时,如果这些行真的被另一个会话锁定,则OPEN立即返回并给出:ORA-0054 :resource busy and acquire with nowait specified. 如果使用 FOR UPDATE 声明游标,则可在DELETE和UPDATE 语句中使用WHERE CURRENT OF cursor_name子句,修改或删除游标结果集

17、合当前行对应的数据库表中的数据行。,SELECT . . . FROM FOR UPDATE OF column, column NOWAIT,SELECT FOR UPDATE 游标,例:从EMP表中查询10号部门的员工情况,将其工资最低定为 1500; DECLARE V_deptno emp.deptno%TYPE :=10;CURSOR emp_cursor IS SELECT empno, sal FROM emp WHERE deptno=v_deptno FOR UPDATE NOWAIT;BEGINFOR emp_record IN emp_cursor LOOPIF emp_

18、record.sal 1500 THENUPDATE emp SET sal=1500 WHERE CURRENT OF emp_cursor;END IF;END LOOP;-COMMIT;END;,游标变量,与游标一样,游标变量也是一个指向多行查询结果集合中当前数据行的指针。但与游标不同的是,游标变量是动态的,而游标是静态的。游标只能与指定的查询相连,即固定指向一个查询的内存处理区域,而游标变量则可与不同的查询语句相连,它可以指向不同查询语句的内存处理区域(但不能同时指向多个内存处理区域,在某一时刻只能与一个查询语句相连),只要这些查询语句的返回类型兼容即可。,声明游标变量,游标变量为一个

19、指针,它属于参照类型,所以在声明游标变量类型之前必须先定义游标变量类型。在PL/SQL中,可以在块、子程序和包的声明区域内定义游标变量参照类型。,TYPE ref_type_name IS REF CURSOR RETURN return_type,其中:ref_type_name为新定义的游标变量类型名称; retuen_type 为游标变量的返回值类型,它必须为记录变量。,声明游标变量,例:声明两个强类型定义游标变量和一个弱类型游标变量 DECLARETYPE deptrecord IS RECORD(Deptno dept.deptno%TYPE,Dname dept.deptno%TY

20、PE,Loc dept.loc%TYPE );TYPE deptcurtype IS REF CURSOR RETURN dept%ROWTYPE;TYPE deptcurtyp1 IS REF CURSOR RETURN deptrecord;TYPE curtype IS REF CURSOR;Dept_c1 deptcurtype;Dept_c2 deptcurtyp1;Cv curtype;,游标变量操作,与游标一样,游标变量操作也包括打开、提取和关闭三个步骤,打开游标变量 :,打开游标变量时使用的是OPENFOR 语句。格式为:OPEN cursor_variable_name |

21、:host_cursor_variable_nameFOR select_statement;其中:cursor_variable_name为游标变量, host_cursor_variable_name为PL/SQL主机环境(如OCI: ORACLE Call Interface,Pro*c 程序等)中声明的游标变量。OPENFOR 语句可以在关闭当前的游标变量之前重新打开游标变量,而不会导致CURSOR_ALREAD_OPEN异常错误。新打开游标变量时,前一个查询的内存处理区将被释放。,游标变量操作,与游标一样,游标变量操作也包括打开、提取和关闭三个步骤,提取游标变量数据 :,使用FETC

22、H语句提取游标变量结果集合中的数据。格式为:FETCH cursor_variable_name | :host_cursor_variable_nameINTO variable , variable| record_variable;其中:cursor_variable_name和host_cursor_variable_name分别为游标变量和宿主游标变量名称;variable和record_variable分别为普通变量和记录变量名称。,游标变量操作,与游标一样,游标变量操作也包括打开、提取和关闭三个步骤,关闭游标变量 :,CLOSE语句关闭游标变量,格式为:CLOSE cursor_

23、variable_name | :host_cursor_variable_name其中:cursor_variable_name和host_cursor_variable_name分别为游标变量和宿主游标变量名称,如果应用程序试图关闭一个未打开的游标变量,则将导致INVALID_CURSOR异常错误。,游标变量应用举例,例:强类型参照游标变量类型 DECLARETYPE emp_job_rec IS RECORD(Employee_id emp.empno%TYPE,Employee_name emp.ename%TYPE,Job_title emp.job%TYPE);TYPE emp_j

24、ob_refcur_type IS REF CURSOR RETURN emp_job_rec;Emp_refcur emp_job_refcur_type ;Emp_job emp_job_rec;,游标变量应用举例,例:BEGINOPEN emp_refcur FOR SELECT empno, ename, job FROM emp ORDER BY deptno;FETCH emp_refcur INTO emp_job;WHILE emp_refcur%FOUND LOOPDBMS_OUTPUT.PUT_LINE(emp_job.employee_id|: |emp_job.empl

25、oyee_name| is a |emp_job.job_title);FETCH emp_refcur INTO emp_job;END LOOP;END;,游标变量应用举例,例:弱类型参照游标变量类型 DECLAREType refcur_t IS REF CURSOR;Refcur refcur_t;TYPE sample_rec_type IS RECORD (Id number,Description VARCHAR2 (30) );sample sample_rec_type;selection varchar2(1) := UPPER (SUBSTR (,游标变量应用举例,例:B

26、EGINIF selection=D THEN OPEN refcur FOR SELECT deptno, dname FROM dept; DBMS_OUTPUT.PUT_LINE(Department data);ELSIF selection=E THEN OPEN refcur FOR SELECT empno, ename| is a |job FROM emp; DBMS_OUTPUT.PUT_LINE(Employee data);ELSE DBMS_OUTPUT.PUT_LINE(Please enter D or E ); RETURN;END IF;DBMS_OUTPUT.PUT_LINE(-);FETCH refcur INTO sample;WHILE refcur%FOUND LOOP DBMS_OUTPUT.PUT_LINE(sample.id|: |sample.description); FETCH refcur INTO sample;END LOOP;CLOSE refcur; END;,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 中等教育 > 小学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报