PL/SQL学习笔记_02_游标
在 PL/SQL 程序中,对于处理多行记录的事务经常使用游标来实现。
为了处理 SQL 语句, ORACLE 必须分配一片叫上下文( context area )的区域来处理所必需的信息,其中包括要处理的行的数目,一个指向语句被分析以后的表示形式的指针以及查询的活动集(active set)。
游标是一个指向上下文的句柄( handle)或指针。通过游标, PL/SQL 可以控制上下文区和处理语句时上下文区会发生些什么事情。
1.处理显示游标
处理显示游标有4个步骤:
(1)定义游标:
CURSOR cursor_name [(parameter [, parameter]…) ] IS 子查询 ;
在指定数据类型时,不能使用长度约束。如 NUMBER(4)、 CHAR(10) 等都是错误的。
(2)打开游标:
OPEN cursor_name [([parameter =>] value [, [parameter =>] value]…)];
就是执行游标所对应的 SELECT 语句,将其查询结果放入工作区,并且指针指向工作区的首部,标识游标结果集合。如果游标查询语句中带有 FOR UPDATE 选项, OPEN 语句还将锁定数据库表中游标结果集合对应的数据行。
(3)提取游标数据:
FETCH cursor_name INTO { variable_list | record_variable };
检索结果集合中的数据行,放入指定的输出变量中。
对该记录进行处理;
继续处理,直到活动集合中没有记录;
(4)关闭游标:
CLOSE cursor_name;
当提取和处理完游标结果集合数据后,应及时关闭游标,以释放该游标所占用的系统资源,并使该游标的工作区变成无效,不能再使用 FETCH 语句取其中数据。
关闭后的游标可以使用 OPEN 语,句重新打开。
注:定义的游标不能有 INTO 子句。
示例1:
declare
--1. 定义游标
cursor salary_cursor is select salary from employees where department_id = 80;
v_salary employees.salary%type;
begin
--2. 打开游标
open salary_cursor; --3. 提取游标
fetch salary_cursor into v_salary; --4. 对游标进行循环操作: 判断游标中是否有下一条记录
while salary_cursor%found loop
dbms_output.put_line('salary: ' || v_salary);
fetch salary_cursor into v_salary;
end loop; --5. 关闭游标
close salary_cursor;
end;
示例2:
/*
利用游标, 调整公司中员工的工资: 工资范围 调整基数
0 - 5000 5%
5000 - 10000 3%
10000 - 15000 2%
15000 - 1%
*/
declare
--定义游标
cursor emp_sal_cursor is select salary, employee_id from employees; --定义基数变量
temp number(4, 2); --定义存放游标值的变量
v_sal employees.salary%type;
v_id employees.employee_id%type;
begin
--打开游标
open emp_sal_cursor; --提取游标
fetch emp_sal_cursor into v_sal, v_id; --处理游标的循环操作
while emp_sal_cursor%found loop
--判断员工的工资, 执行 update 操作
--dbms_output.put_line(v_id || ': ' || v_sal); if v_sal <= 5000 then
temp := 0.05;
elsif v_sal<= 10000 then
temp := 0.03;
elsif v_sal <= 15000 then
temp := 0.02;
else
temp := 0.01;
end if; --dbms_output.put_line(v_id || ': ' || v_sal || ', ' || temp);
update employees set salary = salary * (1 + temp) where employee_id = v_id; fetch emp_sal_cursor into v_sal, v_id;
end loop;
--关闭游标
close emp_sal_cursor;
end;
使用SQL中的 decode 函数
update employees set salary = salary * (1 + (decode(trunc(salary/5000), 0, 0.05,
1, 0.03,
2, 0.02,
0.01)))
2.游标属性
%FOUND | 布尔型属性,当最近一次读记录时成功返回,则值为 TRUE; |
%NOTFOUND | 布尔型属性,与%FOUND 相反; |
%ISOPEN | 布尔型属性,当游标已打开时返回 TRUE; |
%ROWCOUNT | 数字型属性,返回已从游标中读取的记录数。 |
3. 游标的 FOR 循环
FOR index_variable IN cursor_name[value[, value]…] LOOP
-- 游标数据处理代码
END LOOP;
PL/SQL 语言提供了游标 FOR 循环语句,自动执行游标的 OPEN、 FETCH、 CLOSE 语句和循环语句的功能
如果在游标查询语句的选择列表中存在计算列,则必须为这些计算列指定别名后才能通过游标 FOR 循环语句中的索引变量来访问这些列数据。
注:不要在程序中对游标进行人工操作;不要在程序中定义用于控制 FOR 循环
示例1:
/*
利用游标, 调整公司中员工的工资: 工资范围 调整基数
0 - 5000 5%
5000 - 10000 3%
10000 - 15000 2%
15000 - 1%
*/
declare
--定义游标
cursor emp_sal_cursor is select salary, employee_id id from employees; --定义基数变量
temp number(4, 2);
begin
--处理游标的循环操作
for c in emp_sal_cursor loop
--判断员工的工资, 执行 update 操作
--dbms_output.put_line(v_id || ': ' || v_sal); if c.salary <= 5000 then
temp := 0.05;
elsif c.salary <= 10000 then
temp := 0.03;
elsif c.salary <= 15000 then
temp := 0.02;
else
temp := 0.01;
end if; --dbms_output.put_line(v_id || ': ' || v_sal || ', ' || temp);
update employees set salary = salary * (1 + temp) where employee_id = c.id;
end loop;
end;
4.带参数的游标
declare
--定义游标
cursor emp_sal_cursor(dept_id number, sal number) is
select salary + 1000 sal, employee_id id
from employees
where department_id = dept_id and salary > sal; --定义基数变量
temp number(4, 2);
begin
--处理游标的循环操作
for c in emp_sal_cursor(sal => 4000, dept_id => 80) loop
--判断员工的工资, 执行 update 操作
--dbms_output.put_line(c.id || ': ' || c.sal); if c.sal <= 5000 then
temp := 0.05;
elsif c.sal <= 10000 then
temp := 0.03;
elsif c.sal <= 15000 then
temp := 0.02;
else
temp := 0.01;
end if; dbms_output.put_line(c.sal || ': ' || c.id || ', ' || temp);
--update employees set salary = salary * (1 + temp) where employee_id = c.id;
end loop;
end;
5.隐式游标
显式游标主要是用于对查询语句的处理,尤其是在查询结果为多条记录的情况下;而对于非查询语句,如修改、删除操作,则由ORACLE系统自动地为这些操作设置游标并创建其工作区,这些由系统隐含创建的游标称为隐式游标, 隐式游标的名字为 SQL,这是由 ORACLE 系统定义的。对于隐式游标的操作,如定义、打开、取值及关闭操作,都由 ORACLE系统自动地完成,无需用户进行处理。用户只能通过隐式游标的相关属性,来完成相应的操作。在隐式游标的工作区中,所存放的数据是与用户自定义的显示游标无关的、最新处理的一条SQL语句所包含的数据。
调用格式为: SQL%
--更新指定员工 salary(涨工资 10),如果该员工没有找到,则打印”查无此人”信息 begin
update employees set salary = salary + 10 where employee_id = 1005; if sql%notfound then
dbms_output.put_line('查无此人!');
end if;
end;
PL/SQL学习笔记_02_游标的更多相关文章
- PL/SQL学习笔记之游标
一:游标 Oracle会创建一个上下文区域,用于处理SQL语句,其中包含需要处理的语句.处理结果等等. 游标指向这一上下文的区域. PL/SQL通过控制游标在上下文区域移动,来获取SQL语句的结果信息 ...
- ORALCE PL/SQL学习笔记
ORALCE PL/SQL学习笔记 详情见自己电脑的备份数据资料
- Oracle之PL/SQL学习笔记
自己在学习Oracle是做的笔记及实验代码记录,内容挺全的,也挺详细,发篇博文分享给需要的朋友,共有1w多字的学习笔记吧.是以前做的,一直在压箱底,今天拿出来整理了一下,给大家分享,有不足之处还望大家 ...
- [Oracle] PL/SQL学习笔记
-- 1. 使用一个变量 declare -- Local variables here v_name ); begin -- Test statements here select t.user_n ...
- PL\SQL学习笔记
注释 单行--多行 一.declare一般用于做变量的申明.begin 程序体开始执行 end; 程序体结束exception .. dbms_output.put_line('绝对值'||v_ab ...
- PL/SQL学习笔记_01_基础
PL/SQL语句可以在Oracle客户端的 SQL窗口或者 command 窗口中运行 在SQL窗口中运行步骤同 SQL语句 在command 窗口中运行的步骤如下: 1)File—new com ...
- PL/SQL学习笔记程序单元
一:程序单元组成 一个PL/SQL程序单元主要包括三部分: 声明与定义部分:声明变量.常量.类型等:定义过程.函数等: 执行部分:执行PL/SQL语句:调用过程.参数:处理游标等: 异常处理部分:处理 ...
- PL/SQL学习笔记之包
一:包 包是由一组相关的函数,过程,变量,游标等PL/SQL程序设计元素的组合而成的一个PL/SQL程序单元,相当于Java中的类. 包的主要作用是封装:把相同或相似的东西归类,方便维护和管理,提高开 ...
- PL/SQL学习笔记之异常
一:异常 程序执行过程中出现错误情况被称为异常,主要有两种类型的异常: 系统定义的异常 用户定义的异常 二:系统定义的异常 Exception Oracle Error SQLCODE 描述 ACCE ...
随机推荐
- mongodb 安装及使用
https://www.cnblogs.com/shileima/p/7823434.html
- Zxing二维码解析——图文转换
一:文字转化为二维码图片. package com.xhm.tool; import java.util.Hashtable; import android.graphics.Bitmap; impo ...
- Cloneable 和clone的区别和联系
设计模式----原型模式时候,涉及到的复制克隆, Cloneable 接口,内部是没有任何方法的, 这个接口其实是一个标记性的接口,和Serializable是一样的,都是标记使用, 在类实现了这个C ...
- META-INF中的INF的意思
1 META是元的意思,比如meta data,元数据. 2 什么是meta data 元数据就是描述其它数据的数据,比如web page中的meta data,包括关键字,对该网页的描述等等. 3 ...
- html5plus (H5 WebApp)
是什么? 它是增强版的手机浏览器引擎, 让HTML5达到原生水平, 它提供WebApp的规范. 它结合MUI(前端框架) + HBuilder(开发工具) 即可迅速实现开发一个app. 快速起步? 1 ...
- Js编写的菜单树
只需要提供这种JSON格式就ok了 其他的都可以直接引用这个代码进去 var testMenu=[ { "name": "一级菜单", "submen ...
- 'gbk' codec can't encode character '\xa0' in position 34: illegal multibyte sequence
今天在爬某广告贼多的网站遇到的问题,简单记录下
- java基础入门之数组排序冒泡法
public class ArrayTest03{ /* Name:数组排序,冒泡法 Power by :Stuart Date:2015-4-23*/ public static void main ...
- STM32L0 HAL库 TIM定时1s
STM32L0的定制器资源: 本实验使用TIM6 HSI频率是16Mhz,则单指令周期是1/16Mhz 预分频设置为1600,则每跑1600下,定时器加1,相当于定时器加1的时间是1600*(1/16 ...
- 第13条:合理利用try/expect/else/finally结构中的每个代码块
核心知识点: (1)无论try块是否发生异常,都可以使用try/finally复合语句中地finally块来执行清理工作. (2)顺利运行try块后,若想使某些操作能在finally块地清理代码之前执 ...