Oracle —— 游标

1.隐式游标

  • 可以理解为指针,实际上是一大块内存区域,可以把表中的一行数据存储在游标中做处理
  • 在pl/sql语句中执行增删改操作,以及单行查询的时候,会自动触发隐式游标,游标名叫sql
  • 隐式游标有如下属性
    • %found:触发游标的增删改查操作是否被执行,执行了,返回true
    • %notfound
    • %rowcount:增删改查操作影响的行数
    • %isopen:判断游标是否被打开:隐式游标的%isopen属性永远为false
begin
	update emp set ename='张三丰' where empno=7369;
	/*IF SQL%FOUND  THEN
		DBMS_OUTPUT.PUT_LINE('表已更新');*/
  if sql%rowcount>0  THEN
		dbms_output.put_line('表已更新');
  end if;
  
  if sql%isopen then
    dbms_output.put_line('游标已打开');
  else
    dbms_output.put_lineE('游标已关闭');
	ennd if;
end;
begin
    update emp set deptno=20 where empno=7111;  
    if sql%notfound then
      dbms_output.put_line('编号未找到');
 	  else
		  dbms_output.put_line('数据已更新');
	end if;
end;

select * from emp where empno=7839;

2.显示游标

  • 实现查询结果的循环遍历,显示多行查询结果
  • 显式游标需要显式地定义,打开,运行,关闭
  • 显式游标:用于进行表中数据的循环打印
  • 实现步骤:
    • 在declare中声明游标:cursor 游标名(参数名 数据类型) is 查询语句;
    • 在begin中打开游标:open 游标名(参数);
    • 在loop循环中提取游标数据存到变量:fetch 游标名 into 变量;
    • 在end前,关闭游标,close 游标名;
  • for循环中
    • 声明游标
    • 使用游标:for 变量名 in 游标名
  • 循环显示emp表中的员工姓名
declare
 v_ename emp.ename%type;
 --1.定义显式游标:cursor 游标名 is 查询语句;
 cursor c_ename is select ename from emp; 
begin
  --2.打开游标
  open c_ename;
  --查询结果不止一行
  loop
  --3.提取游标值,存到变量
  fetch c_ename into v_ename;
  dbms_output.put_line('员工姓名是:'||v_ename);
  exit when c_ename%notfound;
  end loop;
  --4.关闭游标
  close c_ename;
end;

(1)带参数的显式游标

--查询部门编号是20的员工编号,姓名和薪资
declare
cursor c_emp(dno number) is select empno,ename,sal from emp where deptno=dno;
--游标行中存储了几列数据,下面就需要定义几个变量去接收
v_empno emp.empno%type;
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
  open c_emp(20);
  loop
    fetch c_emp into v_empno,v_ename,v_sal;
    dbms_output.put_line('员工编号是:'||v_empno||'姓名是:'||v_ename||'薪资是:'||v_sal);
    exit when c_emp%notfound;
  end loop;
  close c_emp;
end;

(2)引入游标行变量

declare
cursor c_emp(dno number) is select empno,ename,sal from emp where deptno=dno;
r_emp c_emp%rowtype;--游标行变量,存储三列数据
begin
  open c_emp(20);--打开游标的时候传参
  loop
    fetch c_emp into r_emp;
    dbms_output.put_line('员工编号是:'||r_emp.empno||'姓名是:'||r_emp.ename||'薪资是:'||r_emp.sal);
    exit when c_emp%notfound;
  end loop;
  close c_emp;
end;

(3)引入for循环打印游标

  • 存储游标中的值的变量不需要声明,游标的打开,提取和关闭都不需要了
declare 
cursor c_emp(dno number) is select empno,ename,sal from emp where deptno=dno;
begin
  for r_emp in c_emp(20)
    loop
      dbms_output.put_line('员工编号是:'||r_emp.empno||'姓名是:'||r_emp.ename||'薪资是:'||r_emp.sal);
    end loop;    
end;

(4)用游标来更新、删除行(看明白即可)

  • 给emp表中的员工加薪,薪资最高的不加钱,第二高的加100,以此类推
DECLARE 
--用游标更新/删除行时,需要在select后面加上for update
   CURSOR c_emp IS
     SELECT empno,ename,sal FROM emp ORDER BY sal DESC FOR UPDATE;    
   v_increase NUMBER:=0; --增加的工资数
   v_new_sal NUMBER;     --新工资
BEGIN
   FOR r_emp IN c_emp 
     LOOP
     v_new_sal:=r_emp.sal+v_increase;
     --用游标做更新操作,需要末尾加上where current of 游标名
     UPDATE emp SET sal=v_new_sal WHERE CURRENT OF c_emp;
     DBMS_OUTPUT.PUT_LINE(r_emp.empno||'的员工初始薪资为:'
     ||r_emp.sal||',涨后的薪资为:'||v_new_sal);
     v_increase:=v_increase+100;
   END LOOP;
END;

3.REF游标(了解)

  • 定义一个游标,在具体使用的时候根据需要去指向具体的表;
posted @ 2020-07-13 15:20  Hyx'  阅读(3)  评论(0)    收藏  举报