oracle学习笔记(十八) PL/SQL 游标

游标

说明

查询结果的光标,相当于java中的一个迭代器,方便遍历操作

可使用的属性

  • %FOUND
    SQL语句查询或影响了一行或多行时为 TRUE。如:mycursor%FOUND
  • %NOTFOUND
    SQL语句没有影响任何行时为 TRUE。如:mycursor%NOTFOUND
  • %ROWCOUNT
    SQL语句查询或影响的行数。如:mycursor%ROWCOUNT
  • %ISOPEN
    检查游标是否打开,隐式游标始终为FALSE。如:mycursor%ISOPEN

隐式游标

自动声明,自动打开,自动关闭,名称为SQL
只能处理单行数据

declare
emp_t employee%rowtype;
begin
	select * into emp_t from employee where empno = 7859;	
	if SQL%found then
	dbms_output.putline()
	end if;
end;
/

显式游标

遍历输出

cursor 游标名称[(参数列表)] IS select_statement;

--使用游标遍历查询结果并输出
declare
	--给查询结果建立一个游标
	cursor cv_emp is select * from employee;
	v_emp employee%rowtype;
begin
	--使用for循环,游标会自动打开,移动和关闭
	for v_emp in cv_emp loop
		--这里只输出了员工编号和员工姓名
		dbms_output.put_line(v_emp.empno||','||v_emp.ename);
	end loop;
end;
/

游标使用

  1. 声明游标: cursor 游标名称[(参数列表)] IS select_statement;
  2. 打开游标: open 游标名称[(参数列表)];
  3. 从游标中提取数据(移动游标)到变量: FETCH 游标名称 INTO 变量列表....;
  4. 关闭游标: close 游标名称;

游标开始的时候是处于第一行之前,需要移动

--loop循环使用显示游标
--输出全部员工的信息
declare
	cursor cv_emp 
	 is select empno,ename,job,sal,hiredate from employee;
	--声明一个可存储游标行的变量
	rec_emp cv_emp%rowtype;
	i number := 1;
begin
	open cv_emp;
	loop
		--会使游标向下移动,并将游标所指向的数提取到指定的变量中
		fetch cv_emp into rec_emp;
		exit when cv_emp%notfound;--找不到数据就退出循环
		dbms_output.put_line(i||'. '||rec_emp.empno||', '
						   ||rec_emp.ename||', '
						   ||rec_emp.job||','
						   ||rec_emp.sal||','
						   ||rec_emp.hiredate);
		i := i+1;
	end loop;
	close cv_emp;--关闭游标
end;
/

--使用while循环
declare
   --1. 声明游标
   cursor cv_emp 
     is select empno,ename,job,sal,hiredate from employee;
     
   rec_emp cv_emp%rowtype;
   i number := 1;
begin
	open cv_emp;--2.打开游标
	fetch cv_emp into rec_emp;--进入循环前就得移动游标
	while cv_emp%found loop
		dbms_output.put_line(i||'. '||rec_emp.empno||', '
						   ||rec_emp.ename||', '
						   ||rec_emp.job||','
						   ||rec_emp.sal||','
						   ||rec_emp.hiredate);
		 fetch cv_emp into rec_emp;
		 i := i+1;
	end loop;
	close cv_emp;--关闭游标
end;
/

带参数游标使用

--对所有的"销售员"(SALESMAN)增加佣金500.
declare
	cursor cv_emp(v_job employee.job%type) is select * from employee where job = v_job;
	v_emp employee%rowtype;
begin
	for v_emp in cv_emp('SALESMAN') loop
		--使用主键约束,更新特定行
		update employee set sal = sal +500 where empno = v_emp.empno;
	end loop;
commit;	
end;
/

游标更新数据

一般更新操作,需要一个条件,来指定需要更新的该条数据,一般使用主键来指定。
如果不想使用主键来指定,还可以使用游标当作指定条件,这就是游标更新行

--对所有的"销售员"(SALESMAN)增加佣金500.

--普通方式更新数据
declare
	cursor cv_emp(v_job employee.job%type) is select * from employee where job = v_job;
	v_emp employee%rowtype;
begin
	for v_emp in cv_emp('SALESMAN') loop
		--使用主键约束,更新特定行
		update employee set sal = sal +500 where empno = v_emp.empno;
	end loop;
commit;	
end;
/

--使用游标更新数据
declare
	cursor cv_emp(v_job employee.job%type) is select * from employee where job = v_job for update;
	v_emp employee%rowtype;
begin
	open cv_emp('SALESMAN');
	loop
		fetch cv_emp into v_emp;
		--使用游标定位特定行
		update employee set sal = sal +500 where current of cv_emp;
		end if;
		exit when ev_emp%notfound;
	end loop;
	commit;	
	close cv_emp;
end;
/

REF游标

引用游标,动态游标
动态游标

posted @ 2019-05-29 14:57  Stars-one  阅读(682)  评论(0编辑  收藏  举报