oracle PL/SQL(procedure language/SQL)程序设计之游标cursors
游标 Cursors--Conception
每一条被Oracle服务器执行的SQL语句都有一个独立的游标与之相关联:
隐式游标 Implicit cursors: 用于所有的DML和PL/SQL的SELECT语句。
显示游标 Explicit cursors: 被程序显示声明和命名。
所定义的SQL语句必须只包含select语句,并且不能用insert、update或delete关键字。
当select语句可能返回零或多于一行时,必须用显式游标。
当Select语句预计只返回一行时,隐式游标将做得更好。
SQL游标属性(隐式游标)
使用SQL游标属性,能够测试SQL语句的执行结果。
在PL/SQL中用“SQL”引用最近的隐式游标。在程序中不能用OPEN、FETCH和CLOSE语句控制隐式游标。显示游标在后续课程中讲解。

从表rooms中删除指定的room_id行,并打印删除的行数。
VARIABLE rows_deleted VARCHAR2(100)
DECLARE
v_empno NUMBER := 7788;
BEGIN
DELETE FROM emp
WHERE empno = v_room_id;
:rows_deleted := SQL%ROWCOUNT||' rows deleted.';
END;
PRINT rows_deleted
显示游标的功能
能够一行一行的处理多行查询结果。
能够记录和跟踪当前正在处理的行。
在PL/SQL块中允许程序手工控制游标。

(1)创建游标语法:
CURSOR cursor_name IS
select_statement;
在游标声明中不能包含INTO子句。
如果处理的行要求特定的顺序,在查询语句中可以使用 ORDER BY子句。
examples;
DECLARE
CURSOR c1 IS
SELECT empno, ename
FROM emp;
CURSOR c2 IS
SELECT *
FROM dept
WHERE deptno = 10;
BEGIN
...
(2)打开游标
OPEN cursor_name;
打开游标
执行查询。
活动集(查询结果的行的集合)被确定。
活动集的指针指向第一行。
如果查询没有返回行,不会抛出异常。
提取一行后,应该使用游标属性测试结果。
(3)从游标中提取数据
FETCH cursor_name INTO [variable1, variable2, ...]
| record_name];
提取当前行的值存储到PL/SQL变量中。
变量的类型必须与查询的选择列表的类型相兼容。
变量的数量必须与查询的选择列表的数量相同。
测试游标是否包含行。如果没有提取出值,则说明在处理的活动集中没有剩下需要处理的行并且不会有错误记录。
例子
DECLARE(声明数据变量)
v_ename emp.ename%TYPE;
v_sal emp.sal%TYPE;
v_empRecord emp%ROWTYPE;
CURSOR cur_AllEmp IS(创建游标)
SELECT * FROM emp;
BEGIN
OPEN cur_AllEmp;打开游标
FETCH cur_AllEmp INTO v_empRecord;(从游标中提取数据)
FETCH cur_AllEmp INTO v_ename, v_sal;(error)
END;
例子 从scott.emp表中查询所有记录,利用游标获取前两行记录并输出ename、job、sal中的值
DECLARE
CURSOR c1 IS SELECT * FROM emp; 创建游标)
emp_rec emp%ROWTYPE; --定义一个和表结构完全一致的记录变量
BEGIN
OPEN c1;
FETCH c1 INTO emp_rec;
dbms_output.put_line('姓名是:'||emp_rec.ename|| '工作是:'||emp_rec.job|| '工资是:'||emp_rec.sal);
FETCH c1 INTO emp_rec;
dbms_output.put_line('姓名是:'||emp_rec.ename||'工作是:'||emp_rec.job|| '工资是:'||emp_rec.sal);
CLOSE c1;
END;
关闭游标 CLOSE cursor_name;
当所有的活动集都被检索以后,游标就应该关闭。
如果需要,可以在重新打开游标。
一旦关闭了游标,再从该游标提取数据就将是非法的。这样做会产生一个Oracle错误。
游标提取控制
使用LOOP循环实现显示游标多行数据处理。
反复使用Fetch来提取每一行数据。
使用%NOTFOUND属性来判断提取(Fetch)行是否不成功。
使用%FOUND显示游标属性来判断每一次提取(Fetch)操作是否成功。
%ISOPEN属性
只有当游标打开是才能进行提取(Fetch)行的操作。
在进行提取(Fetch)行操作之前,使用%ISOPEN属性测试游标是否打开。
Example
IF NOT c1%ISOPEN THEN
OPEN c1;
END IF;
LOOP
FETCH c1...
使用%ROWCOUNT游标属性,返回到目前位置由游标返回的行的数目。
使用%NOTFOUND游标属性,作为LOOP循环的退出条件。
例子 使用游标实现逐行输出scott.emp表中部门编号为10的员工姓名和工资。
DECLARE
CURSOR emp_cursor IS 创建游标
SELECT ename,sal FROM emp WHERE deptno=10;
emp_record emp%ROWTYPE;
BEGIN
OPEN emp_cursor ;打开游标
LOOP 建立loop循环
FETCH emp_cursor INTO emp_record.ename,emp_record.sal; 、、提取数据
EXIT WHEN emp_cursor%NOTFOUND; //退出循环
dbms_output.put_line('ename: '||emp_record.ename||' sal:'||emp_record.sal);
END LOOP;//
dbms_output.put_line('row count:'||emp_cursor%rowcount);
CLOSE emp_cursor;//关闭游标
END;
游标的FOR循环
FOR record_name IN cursor_name LOOP
statement1;
statement2;
. . .
END LOOP;
游标的FOR循环能够便捷的处理显示游标。
FOR循环中的循环控制变量不需要事先定义。
在游标的FOR循环之前,系统能够自动打开游标;在FOR循环结束后,系统能够自动关闭游标,不需要人为操作。
在游标的FOR循环过程中,系统能够自动执行FETCH语句;每一次循环,系统就自动执行一次FETCH语句,将游标指向的当前行记录存入循环控制变量中
例子使用FOR循环实现逐行输出emp表中部门编号为10的员工姓名和工资。
DECLARE
CURSOR emp_cursor IS
SELECT ename,sal FROM scott.emp WHERE deptno=10;
BEGIN
FOR emp_record IN emp_cursor LOOP
dbms_output.put_line('ename: '||emp_record.ename||' sal:'||emp_record.sal);
END LOOP;
/* 该命令无效,因为FOR循环结束后游标自动关闭
dbms_output.put_line('row count:'||emp_cursor%rowcount); */
END;
游标提取循环
例子使 用游标查询emp表中的所有记录,并在程序块中输出工资最高的前五行记录。
DECLARE
CURSOR cur IS SELECT * FROM scott.emp ORDER BY sal DESC;
BEGIN
FOR rec IN cur LOOP
IF cur%ROWCOUNT<=5 THEN [cur%ROWCOUNT 从1 开始]
dbms_output.put_line('ename:'||rec.ename||’sal:'||rec.sal);
ELSE
EXIT;
END IF;
END LOOP;
END;
使用子查询的游标FOR循环(不需要定义游标)
BEGIN
FOR emp_record IN ( SELECT empno, ename
FROM emp) LOOP (就是用DML语句 代替了游标而已,其他到没有啥子)
-- implicit open and implicit fetch occur
IF emp_record.empno = 7839 THEN
...
END LOOP; -- implicit close occurs
END;
带参数的游标
CURSOR cursor_name(parameter_name datatype) IS select_statment;
使用open命令打开带参数的游标时,需要给游标传递实参值。
实例 定义参数游标,查询指定部门的员工姓名
DECLARE
--定义游标参数no,参数类型为number类型
CURSOR emp_cursor( no NUMBER) IS
SELECT ename FROM emp WHERE deptno=no;
emp_rec emp_cursor%ROWTYPE;
BEGIN
--打开参数游标时,指明一个替代变量作为游标参数的值
OPEN emp_cursor(&no);
LOOP
FETCH emp_cursor INTO emp_rec;
EXIT WHEN emp_cursor%NOTFOUND;
dbms_output.put_line('ename:'||emp_rec.ename);
END LOOP;
CLOSE emp_cursor;
END;
oracle PL/SQL(procedure language/SQL)程序设计之游标cursors的更多相关文章
- oracle PL/SQL(procedure language/SQL)程序设计
PL/SQL(procedure language/SQL)语言是Oracle对SQL语言的过程化扩充,是一个完整的编程语言.PL/SQL实现了过程化语句(如分支.循环等)与SQL语句的无缝连接,将过 ...
- Oracle笔记--PL/SQL(Procedure Language & Structured Query Language)
1.PL/SQL是一种高级数据库程序设计语言,专门用于在各种环境下对Oracle数据库进行访问.该语言集成于数据库服务器中,所以PL/SQL代码可以对数据进行快速高效的处理. 2.PL/SQL是对SQ ...
- oracle PL/SQL(procedure language/SQL)程序设计之异常(exception)
什么是异常?在PL/SQL中的一个标识.在程序运行期间被触发的错误.异常是怎样被触发的?产生一个Oracle错误.用户显示触发.怎样处理异常?用异常处理句柄捕获异常.传播异常到调用环境. 捕获异常 E ...
- oracle PL/SQL(procedure language/SQL)程序设计之函数+过程+包
匿名PL/SQL块回顾 DECLARE (可选) 定义在PL/SQL块中要使用的对象BEGIN (必须) 执行语句EXCEPTION (可选) 错误处理语句END; (必须)匿名块( ...
- oracle PL/SQL(procedure language/SQL)程序设计之函数+过程+包(转)
匿名PL/SQL块回顾 DECLARE (可选) 定义在PL/SQL块中要使用的对象 BEGIN (必须) 执行语句 EXCEPTION (可选) 错误处理语句 END; (必 ...
- oracle PL/SQL(procedure language/SQL)程序设计之触发器(trigger)
创建触发器 触发器类似于过程和函数,都拥有声明.执行和异常处理过程的带名PL/SQL块.与包类似,触发器必须存储在数据库中.前面已经讲过,过程是显式地通过过程调用执行的,同时过程调用可以传递参数.与之 ...
- oracle PL/SQL(procedure language/SQL)程序设计(在PL/SQL中使用SQL)
在PL/SQL程序中,允许使用的SQL语句只有DML和事务控制语句,使用DDL语句是非法的.使用SELECT语句从数据库中选取数据时,只能返回一行数据.使用COMMIT, ROLLBACK, 和SA ...
- oracle PL/SQL(procedure language/SQL)程序设计--控制结构(if else )
IF逻辑结构:IF-THEN-END IFIF-THEN-ELSE-END IFIF-THEN-ELSIF-END IF 语法 IF condition THEN statements;[ELSIF ...
- oracle PL/SQL(procedure language/SQL)程序设计(续集)之PL/SQL函数
PL/SQL函数 examples:“ 构造一个邮件地址 v_mailing_address := v_name||CHR(10)|| ...
随机推荐
- 20140102-lua binder另一只轮子的雏形
书接上一回,说到要继续丰富对类型的处理.那么如何才能做到呢,应该是要支持自定义的,所以这一回要讲的就是在前面的基础上,增加支持自定义部分,其中包含以下几个部分 函数的默认参数设置,包括有几个默认参数和 ...
- 解决CSS各种IE各种兼容问题(Google解决方案)
google的 ie7 – js中是一个JavaScript库(解决IE与W3C标准的冲突的JS库),使微软的Internet Explorer的行为像一个Web标准兼容的浏览器,支持更多的W3C标准 ...
- WPF的DataGrid绑定ItemsSource后第一次加载数据有个别列移位的解决办法
最近用WPF的DataGrid的时候,发现一个很弱智的问题,DataGrid的ItemsSource是绑定了一个属性: 然后取数给这个集合赋值的时候,第一次赋值,就会出现列移位 起初还以为是显卡的问题 ...
- [转载]NoSQL数据库的基础知识
关系型数据库和NoSQL数据库 什么是NoSQL 大家有没有听说过“NoSQL”呢?近年,这个词极受关注.看到“NoSQL”这个词,大家可能会误以为是“No!SQL”的缩写,并深感愤怒:“SQL怎么会 ...
- 利用C#实现对excel的写操作
一.COM interop 首先我们要了解下何为COM Interop,它是一种服务,可以使.NET Framework对象能够与COM对象通信.Visual Studio .NET 通过引入面向公共 ...
- 全代码实现ios-1
第一次接触ios开发时,就决定用代码开发,而不用ib.因为被ib的各种控件的联线弄得一头雾水,而且ib和storyboard变动太快了. 开始的时候真是麻烦,因为网上关于全代码开发的例子太少了,大多数 ...
- VC++ 网络编程总结(二)
2.基本的Windows Socket API编程 需要在程序中添加下面的包含语句:#include <winsock2.h> #pragma comment( lib, " ...
- Codeforces Round #335 (Div. 2) C. Sorting Railway Cars 动态规划
C. Sorting Railway Cars Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.codeforces.com/conte ...
- (转)用AGG实现高质量图形输出(四)
AGG的字符输出 字符输出,对于AGG来说,这个功能可以处于显示流程的 不同位置.比如字体引擎可直接处于“Scanline Rasterizer”层向渲染器提供已处理完毕的扫描线,也可以处于“Vert ...
- iOS开发——动画总结OC篇&所有常用动画总结
所有常用动画总结 先来装下B,看不懂没关系,其实我也看不懂-