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)|| ...
随机推荐
- hdoj 5355 Cake(分析+二分)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5355 分蛋糕的题目,有1-n大小的n个蛋糕,要求平均分成m份,不能切开蛋糕 #include<s ...
- 有关ListBox
如何拿到Source:从SQL,从XML file SQL:一个是ObjectDataProvider //用linq方法拿到SQL data,wrap到一个IEnumerable<Custom ...
- android 获取手机型号,本机电话号码,SDK版本以及firmwarw版本号(即系统版本号)
Android开发平台中,可通过TelephonyManager 获取本机号码. TelephonyManager phoneMgr=(TelephonyManager)this.getSystemS ...
- 玩转变量、环境变量以及数学运算(shell)
变量和环境变量 var=value 给变量赋值,输出语句:$ echo $var或者是$ echo ${var},记住中间有个空格 例如:name="coffee" age ...
- tab栏切换的特殊效果(类似网易的登陆栏效果)
代码显示效果如上图所示: 需求说明: 在实际需求中,会遇到这样的情况:不仅是要展示选项卡的内容,而且还有可能在选项卡中需求顾客填写相关内容,而这些内容是顾客如果想了解更深层次的,就会继续填写右边的内容 ...
- C#实现Combobox自动匹配字符
不多说了,如图,应客户要求,下拉框中需要自动匹配字符,可能有些人一早就对此很熟,但相对于我还是首次使用,还是花了一点时间,现记录下来,也希望能帮助大家更好的理解. 首先要设定Combobox的Drop ...
- 记录一些在VPS上折腾的东西
折腾这些东西,总是要经常借助搜索引擎找答案,找的次数多了,也就烦了,不想总是做重复工作. 所以把做过的一些事情记录一下,加深一下印象. 1.安装python2.7 VPS上面的太老了,之前安装的,过程 ...
- 【M34】如何在同一个程序中结合C++和C
1.C++和C混合编程的时候,需要考虑产生的目标文件的兼容性. 2.名称重整,为什么要搞出名称重整? 连接器要求所有方法名必须独一无二.对于C语言,没问题.C++支持过载,也就是方法名相同,形参表不同 ...
- netcdf入门(转)
一.概述 NetCDF全称为network Common Data Format,中文译法为“网络通用数据格式”,对程序员来说,它和zip.jpeg.bmp文件格式类似,都是一种文件格式的标准.ne ...
- IOS 7 Study - UIViewController
Presenting and Managing Views with UIViewController ProblemYou want to switch among different views ...