极度郁闷,有一段时间没登陆51了,今天回来竟然把提示问题给弄丢了,猜了半个小时才猜出来。。。。

数据库之游标

上一篇 / 下一篇  2010-01-07 08:24:45 / 个人分类:Oracle

游标是构建在 PL/SQL 中, 用来查询数据,获取记录集合的指针.它可以让开发者一次访问结果集中的一行.
游标可以以编程的方式访问数据,从而完成需要分别在结果集中每个记录上执行的过程代码的任务.
PL/SQL 为所有的 SQL 数据操纵语句(包括返回一行的 select)隐式声明游标,称为隐式游标的原因是用户不能直接命名和控制此类游标.
当用户在 PL/SQL 中使用数据操纵语言(DML)时,Oracle 预先定义一个名为 SQL 的隐式游标,通过检查隐式游标的属性可以获取与最近执行的 SQL 语句相关的信息.

执行 DML 语句之后,隐式游标属性返回信息.隐式游标的属性包括:
%found --在 DML 语句影响一行或多行时,%found 属性才返回 true;
%notfound --在 DML 语句没有影响任何行,则 %notfound 属性才返回 true;
%rowcount --%rowcount 返回 DML 语句影响的行数,如果 DML 语句没有影响任何行,则 %rowcount 属性将返回 0;
%isopen --%isopen 属性返回游标是否已打开的值.在执行 SQL 语句之后,Oracle 自动关闭 SQL 游标,所以隐式游标的 %isopen 属性始终为 false;

显式游标是由用户显式声明的游标.根据在游标中定义的查询,查询返回的行集可以包括零行或多行,这些行称为活动集,游标将指向活动集中的当前行.

使用显式游标的 4 个步骤:
1. 声明游标
2. 打开游标
3. 从游标中获取记录
4. 关闭游标

显式游标的 PL/SQL 程序的 declare 部分声明.格式如下:
cursor cursor_name [(parameter [, parameter...])]
[return return_type] is select_statement;

使用下列语句控制游标:
open --打开游标 格式:open cursor_name [(parameters)];
fetch --从游标中提取行 格式:fetch cursor_name into variables;
close --关闭游标 格式:close cursor_name;

%found --如果执行最后一条 fetch 语句成功返回行.则 %found 的值返回 true;(有数据可取返回 true)
%notfound --如果执行最后一条 fetch 语句未能提取行时.则 %notfound 的值返回 true;(没有数据可取返回 true)
%rowcount --返回到目前为止游标提取的行数.每返回一行,%rowcount 加1;
%isopen --如果游标已经打开,则返回 true. 否则返回 false;

----------------------------------------------------------------隐式游标---------------------------------------------------------------------------
--示例一

set serveroutput on;
begin
update dept set loc = 'BeiJin' where deptno = 80;
if SQL%found then
dbms_output.put_line('表已更新');
else
dbms_output.put_line('编号未找到');
end if;
end;

--示例二

set serveroutput on;
begin
update dept set loc = 'ShangHai' where deptno = 50;
dbms_output.put_line('更新了' || SQL%rowcount || '行');
end;

--示例三

set serveroutput on;
declare
empno_temp number;
job_temp varchar2(20);
begin
empno_temp := &员工编号;
select job into job_temp from emp where empno = empno_temp;
if SQL%rowcount > 0 then
dbms_output.put_line('员工的职位是:' || job_temp);
end if;
exception
when no_data_found then
dbms_output.put_line('员工未找到');
end;

--示例四

set serveroutput on;
declare
empid number;
begin
select empno into empid from emp;
exception
when too_many_rows then
dbms_output.put_line('该查询提取多行');
end;

----------------------------------------------------------------显式游标---------------------------------------------------------------------------
--示例五

set serveroutput on;
declare
ename_temp emp.ename%type;
cursor emp_cur is select ename from emp where sal < 1500;
begin
open emp_cur;
loop
fetch emp_cur into ename_temp;
exit when emp_cur%notfound;
dbms_output.put_line(emp_cur%rowcount || ' 员工: ' || ename_temp);
end loop;
close emp_cur;
end;

--示例六

set serveroutput on;
declare
sal_temp number;
cursor emp_cur is select sal from t_emp where sal < 1500 for update of sal;
begin
open emp_cur;
loop
fetch emp_cur into sal_temp;
exit when emp_cur%notfound;
update t_emp set sal = sal + 500 where current of emp_cur;
end loop;
close emp_cur;
end;

--示例七

set serveroutput on;
declare
deptno_temp emp.deptno%type;
empno_temp emp.empno%type;
ename_temp emp.ename%type;
cursor emp_cur(deptno_param number) is select empno, ename from emp where deptno = deptno_param;
begin
deptno_temp := &部门编号;
open emp_cur(deptno_temp);
loop
fetch emp_cur into empno_temp, ename_temp;
exit when emp_cur%notfound;
dbms_output.put_line(empno_temp || ' ' || ename_temp);
end loop;
close emp_cur;
end;

--示例八

set serveroutput on;
declare
cursor emp_cur is select empno, ename, sal from emp;
begin
for emp_temp in emp_cur loop
dbms_output.put_line('员工编号:' || emp_temp.empno || ' 员工姓名:' || emp_temp.ename || ' 员工工资:' || emp_temp.sal);
end loop;
end;

TAG: 数据库 游标

 

评分:0

我来说两句

Open Toolbar