Oracle19C入门到熟练019-游标

学习要求

有一定关系型数据的操作功底,会SQL语句

教学目标

熟练掌握Oracle数据库PL/SQL编程中游标操作

概念

游标是sql的一个内存工作区,由系统或用户以变量的形式定义,用于临时存储从数据库中提取的数据块。

大白话:PL/SQL操作中,使用select语句查询出一堆的数据,可以用游标数据结构存储这些数据,并提供一套操作这些数据的api。从操作语法上看,类似Java中的迭代器。

操作

游标操作分4个基本步骤

步骤1:定义游标

CURSOR 游标名 [(parameter[, parameter]…)] IS select_statement;

parameter:游标输入的参数,类似定义表中的列一样:格式: 参数名 类型 默认值 eg: ename varchar2(10) :='dafei'

select_statement : 查询语句, 返回的列与parameter定义的类型,顺序一致

步骤2:打开游标

OPEN 游标名[([parameter =>] value[, [parameter =>] value]…)];

select 语句查询数据存储到游标之后,使用open开启游标的操作

步骤3:提取数据

FETCH 游标名 INTO {variable_list | record_variable }

将游标当前遍历的数据放入到指定变量中。注意,每次只能取一行,取完之后自动下移

步骤4:关闭游标

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;	

游标for循环

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;	

你可能感兴趣的:(入门Oracle19C,oracle19c,游标,cursor)