有一定关系型数据的操作功底,会SQL语句
熟练掌握Oracle数据库PL/SQL编程中游标操作
游标是sql的一个内存工作区,由系统或用户以变量的形式定义,用于临时存储从数据库中提取的数据块。
大白话:PL/SQL操作中,使用select语句查询出一堆的数据,可以用游标数据结构存储这些数据,并提供一套操作这些数据的api。从操作语法上看,类似Java中的迭代器。
游标操作分4个基本步骤
CURSOR 游标名 [(parameter[, parameter]…)] IS select_statement;
parameter:游标输入的参数,类似定义表中的列一样:格式: 参数名 类型 默认值 eg: ename varchar2(10) :='dafei'
select_statement : 查询语句, 返回的列与parameter定义的类型,顺序一致
OPEN 游标名[([parameter =>] value[, [parameter =>] value]…)];
select 语句查询数据存储到游标之后,使用open开启游标的操作
FETCH 游标名 INTO {variable_list | record_variable }
将游标当前遍历的数据放入到指定变量中。注意,每次只能取一行,取完之后自动下移
CLOSE 游标名
当提取和处理完游标结果集合数据后,应及时关闭游标,以释放该游标所占用的系统资源, 并使该游标的工作区变成无效。
注意:一旦游标关闭之后就不能在进行fetch了,如果有需要,需要重启开启游标
需求:使用游标方式获取dept表第一条数据,并打印数据
declare
-- 定义游标
cursor c_cursor is select deptno, dname, loc from dept;
v_dept_info c_cursor%rowtype;
begin
-- 打开游标
open c_cursor;
-- 提取数据
fetch c_cursor into v_dept_info;
dbms_output.put_line(v_dept_info.deptno || ' --- ' || v_dept_info.dname || '---' ||v_dept_info.loc);
-- 关闭游标
close c_cursor;
end;
属性 | 返回值类型 | 作用 |
---|---|---|
游标%ISOPEN | boolean | 判断游标是否开启 |
游标%FOUND | boolean | 判断游标是否获取到值 |
游标%NOTFOUND | boolean | 判断游标是否 '没有获取' 到值(常用于 "退出循环") |
游标%ROWCOUNT | 整数 | 返回已从游标中读取的记录数。(非 "总记录数") |
需求:使用游标方式遍历dept表,并打印数据
declare
-- 定义游标
cursor c_cursor is select deptno, dname, loc from dept;
v_dept_info c_cursor%rowtype;
v_isopen boolean;
begin
if c_cursor%ISOPEN then
dbms_output.put_line('开启游标');
else
dbms_output.put_line('没开启游标');
end if;
-- 打开游标
open c_cursor;
if c_cursor%ISOPEN then
dbms_output.put_line('开启游标');
else
dbms_output.put_line('没开启游标');
end if;
-- 提取数据
loop
fetch c_cursor into v_dept_info;
exit when c_cursor%NOTFOUND; -- 结束当游标没有获取到数据
dbms_output.put_line(v_dept_info.deptno || ' --- ' || v_dept_info.dname || '---' ||v_dept_info.loc);
dbms_output.put_line(c_cursor%ROWCOUNT); -- 游标已经读取数据个数
end loop;
-- 关闭游标
close c_cursor;
end;
第二种写法
declare
-- 定义游标
cursor c_cursor is select deptno, dname, loc from dept;
v_dept_info c_cursor%rowtype;
begin
-- 打开游标
open c_cursor;
-- 提取数据
fetch c_cursor into v_dept_info;
while c_cursor%found loop
dbms_output.put_line(v_dept_info.deptno || ' --- ' || v_dept_info.dname || '---' ||v_dept_info.loc);
dbms_output.put_line(c_cursor%ROWCOUNT); -- 游标已经读取数据个数
fetch c_cursor into v_dept_info;
end loop;
-- 关闭游标
close c_cursor;
end;
PL/SQL 语言提供了游标 FOR 循环语句,自动执行游标的 OPEN、FETCH、CLOSE 语句和循环语句的功能;
格式:
FOR 记录变量 IN 游标名称 LOOP
-- 游标处理逻辑
END LOOP;
需求:使用游标方式遍历dept表,并打印数据
declare
-- 定义游标
cursor c_cursor is select deptno, dname, loc from dept;
begin
for v_dept_info in c_cursor loop
dbms_output.put_line(v_dept_info.deptno || ' --- ' || v_dept_info.dname || '---' ||v_dept_info.loc);
end loop;
end;
注意:在for操作中就不要对游标进行open close fetch 操作了
根据游标使用场景分2大类:
静态游标
静态游标又分隐式游标,显示游标
动态游标 (此次不讲,有兴趣可以拓展)
动态游标又分自定义类型,系统类型
特点:
1>自动创建:在执行 DML操作与 select into操作时自动创建
2>自动管理: 无需人为干预(自动声明、打开、关闭)
3>固定名称:默认游标名:'SQL'
declare
v_count number;
begin
insert into dept(deptno, dname, loc) values(70, '小卖部', '广州');
if SQL%found then
dbms_output.put_line('插入成功!');
end if;
update dept set dname = '大卖部' where deptno = 70;
if SQL%found then
dbms_output.put_line('更新成功!');
end if;
delete from dept t where deptno = 70;
if SQL%found then
dbms_output.put_line('删除成功!');
end if;
select count(deptno) into v_count from dept ;
if SQL%found then
dbms_output.put_line('总记录为: ' || v_count);
end if;
if SQL%isopen then
dbms_output.put_line('不可能的,永远不可能走这一步');
else
dbms_output.put_line('系统已自动关闭游标');
end if;
end;
由关键字 cursor 声明,可带参数,也可不带参数
无参数
前面定义那些游标都是无参数游标
有参数
声明游标时,带上参数与参数类型
需求:使用游标分别打印工资大于2000 员工信息跟工资大于3000员工信息
declare
cursor c_emp(v_eid number) is select * from emp where sal > v_eid;
begin
for v_emp_info in c_emp(2000) loop
dbms_output.put_line(v_emp_info.empno || ' --- ' || v_emp_info.ename || '---' ||v_emp_info.sal);
end loop;
dbms_output.put_line('--------------------------');
for v_emp_info in c_emp(3000) loop
dbms_output.put_line(v_emp_info.empno || ' --- ' || v_emp_info.ename || '---' ||v_emp_info.sal);
end loop;
end;