什么是游标
游标的作用
基本原理
cursor 游标名(游标输入参数)
is select语句
-- 游标参数可以有多个
示例:声明游标读取emp表中job='SALEMAN’的职员
declare
cursor cur_emp(var_job in varchar2:='SALEMAN') -- varchar不可以指定长度,其他类型也一样
is select empno,ename,sal
from emp where job = var_job;
OPEN 游标名(参数) -- 参数如果为空,则为默认参数
示例:用上面声明的游标查找job='MANAGER’的人
open cur_emp('MANAGER'); -- 如果没有输入参数,则默认查找SALEMAN
FETCH CUR_NAME INTO {VARIABLE}; -- VARIABLE 一个变量列表或“记录”变量
示例:声明一个检索emp表的游标,搜索职务为 MANAGER 的员工信息,使用 FETCH…INTO 语句和 WHILE 语句来读取游标中所有员工信息,最后输出读取到的信息
-- 去cmd - sqlplus执行
set serveroutput on
declare
cursor cur_emp(var_job in varchar2:='SALMANE') -- 声明游标,检索员工信息
is select empno,ename,sal from emp where job = var_job;
type record_emp is record( -- 声明一个记录类型(RECORD 类型)
-- 定义当前成员变量
var_empno emp.empno%type,
var_ename emp.ename%type,
var_sal emp.sal%type
);
emp_row record_emp; -- 声明一个 record_enp 类型的变量
begin
open cur_emp('MANAGER'); -- 打开游标
fetch cur_emp into emp_row; -- 让游标指向第一行,并将值保存到emp_row中
while cur_emp%found loop
dbms_output.put_line(emp_row.var_ename||'的编号是'||emp_row.var_empno||',工资是'||emp_row.var_sal);
fetch cur_emp into emp_row; -- 让指针指向下一行,并将值保存到emp_row中
end loop;
close cur_emp; -- 关闭游标
end;
/
使用while之前,先试用 FETCH … INTO 将游标指针指向第一行,保证 %FOUND 值为true,从而保证循环条件成立。
-- close 游标名
close cur_emp;
关闭游标后,系统会释放被占用的内存
示例:吧emp表中的 SALESMAN 的工资上调20%,然后使用隐式游标的sql的%ROWCOUNT属性输出上调工资的员工数量
set serveroutput on
begin
update emp set sal=sal*(1+0.2) where job = 'SALESMAN';
if sql%notfound then
dbms_output.put_line('0'); --如果没有数据行被影响
else
dbms_output.put_line(sql%rowcount); --输出受影响的数据行
end if;
end;
/
示例:
delete from emp where empno = emp_id; -- emp_id为一个有值变量
if sql %FOUND then
insert into success valuse(empno); -- 删除成功,写进SUCCESS表里
else
insert into fail valuse(empno); -- 删除失败,写进Fail表里
end if;
与%FOUND相反
示例:
loop
fetch cur_emp into var_empno,var_ename,var_job;
exit when cur_emp%rowcount = 10 -- 只抽取10条记录
...
end loop;
示例:
if cur_emp%isopen tneh
fetch cur_emp into var_empno,var_ename,var_job;
else
open cur_emp;
end if;
定义游标时带上参数,使得在使用游标时根据参数不同所选中的数据行也不同,达到动态使用的目的
示例:声明一个游标检索指定员工的信息.
set serveroutput on
declare
var_ename varchar2(50); -- 声明变量,用来存储员工名称
var_job varchar2(50); -- 声明变量,用来存储员工职务
cursor cur_emp -- 定义游标,检索指定编号的信息
is select ename,job from emp where empno = 7499;
begin
open cur_emp; -- 打开游标
fetch cur_emp into var_ename,var_job; --读取游标,并存储员工名称和职务
if cur_emp%found then
dbms_output.put_line(var_ename || var_job);
else
dbms_output.put_line('无数据');
end if;
end;
/
定义一个游标变量的完整语法
-- 类型名是新的引用类型的名字
-- 返回类型是一个记录类型
TYPE<类型名> IS REF CURSOR
RETURN<返回类型>
OPEN <游标变量> FOR <SELECT语句>
如果游标变量是受限的,则SELECT语句返回的类型必须与游标变量所受限的记录类型匹配
(1)FOR语句遍历隐式游标中的数据时,通常在关键字 IN 后面提供由 SELECT 查询出的结果集,在检索结果集的过程中,ORACL 会自动提供一个隐式的游标SQL。
示例:使用隐式游标查询除JOB为 SALESMAN 的员工并输出
set serveroutput on
begin
for emp_record in(select empno,ename,sal from emp where job = 'SALESMAN') -- 遍历隐式游标中的记录
loop
dbms_output.put_line(emp_record.empno); --输出员工编号
dbms_output.put_line(emp_record.ename); --输出员工姓名
dbms_output.put_line(emp_record.sal); --输出员工薪资
end loop;
end ;
/
(2)使用显示游标时,IN 关键字后面提供游标名称
示例:检索emp表部门编号为30的员工并输出
set serveroutput on
declare
cursor cur_emp is select * from emp where deptno = 30;
begin
for emp_record in cur_emp -- 遍历显示游标中的记录
loop
dbms_output.put_line(emp_record.empno); --输出员工编号
dbms_output.put_line(emp_record.ename); --输出员工姓名
dbms_output.put_line(emp_record.sal); --输出员工薪资
end loop;
end ;
/