oracle之隐式游标和ref游标总结
2011-11-30 10:22
417 查看
游标是构建在PL/SQL中,用来查询数据,获取记录集的指针。
它让开发者 一次访问结果集中一行记录。
在oracle中提供了两种游标: 1 静态游标 2 ref游标
静态游标:静态游标是在编译的时候就被确定。然后把结果集复制到内存中。
静态游标又分为两种:隐式游标和显示游标。
ref游标:ref游标是在运行的时候加载结果集。
先来看看静态游标中的隐式游标。
在PL/SQL中为所有的SQL数据操纵语句(包括返回一行的select)隐式声明游标 称为隐式游标。
主要原因是用户不能直接命名和控制此类游标。
当用户在PL/SQL中使用数据操纵语句(DML)时,oracle预先定义一个名称为SQL的隐式游标,通过检查隐式游标的属性获取与最近执行的SQL语句相关信息。
在执行DML语句之后,隐式游标属性返回信息。
隐式游标属性包括:%found、%notfound、%rowcount、%isopen
1 %found
只有DML语句影响一行或多行时,%found属性才返回true。
declare num number;
begin update emp set empno=123 where empno=111;
if sql%found then dbms_output.put_line('存在记录');
else dbms_output.put_line('不存在记录');
end if;
end;
2 %notfound
%notfound属性作用正好跟%found属性相反。如果DML语句没有影响任何行数 ,则%notfound属性返回true。
declare begin delete from emp where empno=111;
if sql%notfound then dbms_output.put_line('删除失败');
end if;
end;
3 %rowcount
%rowcount属性返回DML语句影响的行数。如果DML语句没有影响任何行数 ,则%rowcount属性将返回0。
declare num number;
begin update emp set empno=123 where empno=111;
if sql%rowcount=0 then dbms_output.put_line('不存在记录');
else dbms_output.put_line('存在记录');
end if;
end;
4 %isopen
%isopen属性判断SQL游标是否已经打开。在执行SQL语句之后,oracle自动关闭SQL 游标,所以隐式游标的%isopen属性始终为false。
在PL/SQL中向标准的select语句增加单独的into子句,就可以将从表或视图中查询记录赋予变量或行变量。
需要注意的是select..into 语句结果必须有且只能有一行。
如果查询没有返回行,PL/SQL将抛出no_data_found异常。
如果查询返回多行,则抛出 too_many_rows 异常。
如果抛出异常,则停止执行,控制权转移到异常处理部分(没有异常处理,则程序中断)。
在引发异常时,将不使用属性%found,%notfound,%rowcount来查明DML语句是否已影响了行数。
declare num number;
begin select empno into num from emp where empno=111;
if sql%rowcount=0 or sql%notfound then dbms_output.put_line('不存在记录');
else dbms_output.put_line('存在记录');
end if;
end;
显示游标
显示游标是由用户显示声明的游标。
根据在游标中定义的查询,查询返回的行集合可以包含零行或多行,这些行称为活动集。
游标将指向活动集中的当前行。
显示游标的操作过程。
使用显示游标的4个步骤:
(1)声明游标
(2)打开游标
(3)从游标中获取结果集
(4)关闭游标
cursor cursor_name [(parameter[,parameter])] [return return_type] is select_statement;
cursor_name 指游标的名称。
parameter 为游标指定输入参数。
return_type 定义游标提取行的行类型。
select_statement 为游标定义查询语句。
open 游标名称
fetch 从游标中提取行
close 关闭游标
1 打开游标,执行游标中定义的查询语句,绑定输入参数,将游标指针指向结果集的BOF位置。
open cursor_name [parameters]
2 fetch 在打开游标之后,可以从游标中提取记录。
fetch cursor_name into variable_name;
fetch是提取结果集中一行记录存储在变量中。
每次提取之后,结果集指针 就向前移动一行。
3 close 在处理游标中的所有行之后,必须关闭游标,以释放分配给游标的所有资源。
close cursor_name 用户可以通过检查游标属性来确定游标的当前状态。
显示游标的属性如下:
%found:如果执行最后一条fetch语句,成功返回行,则%found属性为true。
%notfound:如果执行最后一条fetch语句,未能提取行,则%notfound属性为true。
%isopen:如果游标已经打开,则返回true,否则返回false。
%rowcount:返回到目前为止游标提取的行数。
%rowcount为数字类型属性。在第一 次获取之前,%rowcount为零。当fetch语句返回一行时,则该数加1。
declare info emp%rowtype;
cursor my_cur is select * from emp where empno=111;
begin open my_cur;
dbms_output.put_line(my_cur%rowcount);
loop if my_cur%isopen then fetch my_cur into info;
exit when my_cur%notfound;
dbms_output.put_line(info。empno);
dbms_output.put_line(my_cur%rowcount);
end if;
end loop;
close my_cur;
end;
使用显示游标删除或更新
使用游标时,如果处理过程中需要删除或更新。
在定义游标查询语句时必须使用select..for update语句,而在执行delete或update时使用where current of子句指定游标当前行。
cursor cursor_name is select_statement for update[of column] wait/nowait
在使用for update 子句声明游标之后,可以使用以下语法更新行:
update table_name set column_name=column_value where current of cursor_name;
update命令中使用的列必须出现在for update of子句中select语句必须只包括一个表,而且delete和update语句只有在打开游标并且提取特定行之后才能使用。
declare cursor cur_emp is select * from emp where sal<2000 for update of sal;
num emp%rowtype;
begin open cur_emp;
loop fetch cur_emp into num;
exit when cur_emp%notfound;
update emp set sal=2000 where current of cur_emp;
end loop;
close cur_emp;
end;
带参数的显示游标 PL/SQL中允许显示游标接受输入参数。
用于声明带参数的显示游标语法
cursor cursor_name[<param_name> data_type] [return <return type>] is select_statement declare dept_num emp.deptno%type;
emp_num emp.empno%type;
emp_nam emp.ename%type;
cursor emp_cur(deptparam number) is select empno,ename from emp where deptno=deptparam;
begin dept_num:='&部门编号';
open emp_cur(dept_num);
loop fetch emp_cur into emp_num,emp_nam;
exit when emp_cur%notfound;
dbms_output.put_line(emp_num||' '||emp_nam);
end loop;
close emp_cur;
end;
可以使用循环游标来简化显示游标。
循环游标隐式打开显示游标(不需要open)自动从结果集提取记录,然后处理完所有记录自动关闭游标。
循环游标自动创建%rowtype类型的变量并将此变量用做记录的索引。
循环游标语法如下:
for record_index in cursor_name record_index是PL/SQL自动创建的变量,此变量的属性声明为%rowtype类型。
作用域for循环之内。循环游标的特性有:从游标中提取所有记录之后自动关闭游标。
提取和处理游标中每一条记录提取记录之后%notfound属性为true则退出循环。
如果未有结果集,则不进入循环。
declare cursor emp_cur is select * from emp;
begin for temp in emp_cur loop dbms_output.put_line(temp.ename);
end loop;
end;
循环游标自动打开,提取,关闭。只适用于静态游标
ref游标
隐式游标和显示游标都是静态定义的。
它们在编译的时候结果集就已经被确定。
如果想在运行的时候动态确定结果集,就要使用ref游标和游标变量。
创建ref游标需要两个步骤:
1 声明ref cursor类型
2 声明ref cursor类型变量
语法如下:
type ref_cursor_name is ref cursor [return record_type]
其中,return用于指定游标提取结果集的返回类型。
有return表示是强类型ref游标, 没有return表示是弱类型的游标。弱类型游标可以提取任何类型的结果集。
定义游标变量之后,就可以在PL/SQL执行部门打开游标变量 open cursor_name for select_statement;
declare type emp_cur is ref cursor;
my_cur emp_cur;
num number;
selection varchar(2):='&请输入编号';
begin
if selection='1' then dbms_output.put_line('员工信息');
open my_cur for select deptno from emp;
elsif selection='2'
then dbms_output.put_line('部门信息');
open my_cur for select deptno from dept;
else dbms_output.put_line('请输入员工信息(1)或门部信息(2)');
end if;
fetch my_cur into num;
while my_cur%found loop dbms_output.put_line(num);
fetch my_cur into num;
end loop;
close my_cur;
end;
在PL/SQL中可以执行动态SQL语句,execute immediate语句只能语句处理返回单行或没有返回的SQL语句,ref游标则可以处理返回结果集的动态SQL。
ref游标的声明方法与普通ref游标相同,只是在open时指定了动态SQL字符串。
open cursor_name for dynamic_select_string [using bind_argument_list] declare type sql_cur is ref cursor;
my_cur sql_cur;
emp_info emp%rowtype;
sql_string varchar2(100):='&请输入查询字符串';
begin open my_cur for sql_string;
loop fetch my_cur into emp_info;
exit when my_cur%notfound;
dbms_output.put_line(emp_info。ename);
end loop;
close my_cur;
end;
游标变量的特点:
(1)游标变量可以从不同的结果集中提取记录
(2)游标变量可以做为存储过程参数进行传递
(3)游标变量可以引用游标的所有属性
(4)游标变量可以进行赋值运算 使用游标变量也有一定的限制
(1)for update子句不能与游标变量一起使用
(2)不允许在程序包使用游标变量(可以声明游标类型)
(3)另一台服务器上的子过程不能接受游标变量参数
(4)不能将NULL值赋给游标变量
(5)游标变量不能使用比较运算符
(6)数据库中的列不能存储游标变量
总结:
(1)游标是使用在PL/SQL中,是用来查询数据,获取结果集的指针
(2)游标类型包括隐式游标,显示游标和ref游标
(3)游标属性包括%found,%notfound,%rowcount,%isopen
(4)PL/SQL自动定义隐式游标,以获取最近执行SQL语句信息
(5)循环游标简化处理游标中所有行的查询
(6)在声明ref游标时,不要将它与select语句相关联
它让开发者 一次访问结果集中一行记录。
在oracle中提供了两种游标: 1 静态游标 2 ref游标
静态游标:静态游标是在编译的时候就被确定。然后把结果集复制到内存中。
静态游标又分为两种:隐式游标和显示游标。
ref游标:ref游标是在运行的时候加载结果集。
先来看看静态游标中的隐式游标。
在PL/SQL中为所有的SQL数据操纵语句(包括返回一行的select)隐式声明游标 称为隐式游标。
主要原因是用户不能直接命名和控制此类游标。
当用户在PL/SQL中使用数据操纵语句(DML)时,oracle预先定义一个名称为SQL的隐式游标,通过检查隐式游标的属性获取与最近执行的SQL语句相关信息。
在执行DML语句之后,隐式游标属性返回信息。
隐式游标属性包括:%found、%notfound、%rowcount、%isopen
1 %found
只有DML语句影响一行或多行时,%found属性才返回true。
declare num number;
begin update emp set empno=123 where empno=111;
if sql%found then dbms_output.put_line('存在记录');
else dbms_output.put_line('不存在记录');
end if;
end;
2 %notfound
%notfound属性作用正好跟%found属性相反。如果DML语句没有影响任何行数 ,则%notfound属性返回true。
declare begin delete from emp where empno=111;
if sql%notfound then dbms_output.put_line('删除失败');
end if;
end;
3 %rowcount
%rowcount属性返回DML语句影响的行数。如果DML语句没有影响任何行数 ,则%rowcount属性将返回0。
declare num number;
begin update emp set empno=123 where empno=111;
if sql%rowcount=0 then dbms_output.put_line('不存在记录');
else dbms_output.put_line('存在记录');
end if;
end;
4 %isopen
%isopen属性判断SQL游标是否已经打开。在执行SQL语句之后,oracle自动关闭SQL 游标,所以隐式游标的%isopen属性始终为false。
在PL/SQL中向标准的select语句增加单独的into子句,就可以将从表或视图中查询记录赋予变量或行变量。
需要注意的是select..into 语句结果必须有且只能有一行。
如果查询没有返回行,PL/SQL将抛出no_data_found异常。
如果查询返回多行,则抛出 too_many_rows 异常。
如果抛出异常,则停止执行,控制权转移到异常处理部分(没有异常处理,则程序中断)。
在引发异常时,将不使用属性%found,%notfound,%rowcount来查明DML语句是否已影响了行数。
declare num number;
begin select empno into num from emp where empno=111;
if sql%rowcount=0 or sql%notfound then dbms_output.put_line('不存在记录');
else dbms_output.put_line('存在记录');
end if;
end;
显示游标
显示游标是由用户显示声明的游标。
根据在游标中定义的查询,查询返回的行集合可以包含零行或多行,这些行称为活动集。
游标将指向活动集中的当前行。
显示游标的操作过程。
使用显示游标的4个步骤:
(1)声明游标
(2)打开游标
(3)从游标中获取结果集
(4)关闭游标
cursor cursor_name [(parameter[,parameter])] [return return_type] is select_statement;
cursor_name 指游标的名称。
parameter 为游标指定输入参数。
return_type 定义游标提取行的行类型。
select_statement 为游标定义查询语句。
open 游标名称
fetch 从游标中提取行
close 关闭游标
1 打开游标,执行游标中定义的查询语句,绑定输入参数,将游标指针指向结果集的BOF位置。
open cursor_name [parameters]
2 fetch 在打开游标之后,可以从游标中提取记录。
fetch cursor_name into variable_name;
fetch是提取结果集中一行记录存储在变量中。
每次提取之后,结果集指针 就向前移动一行。
3 close 在处理游标中的所有行之后,必须关闭游标,以释放分配给游标的所有资源。
close cursor_name 用户可以通过检查游标属性来确定游标的当前状态。
显示游标的属性如下:
%found:如果执行最后一条fetch语句,成功返回行,则%found属性为true。
%notfound:如果执行最后一条fetch语句,未能提取行,则%notfound属性为true。
%isopen:如果游标已经打开,则返回true,否则返回false。
%rowcount:返回到目前为止游标提取的行数。
%rowcount为数字类型属性。在第一 次获取之前,%rowcount为零。当fetch语句返回一行时,则该数加1。
declare info emp%rowtype;
cursor my_cur is select * from emp where empno=111;
begin open my_cur;
dbms_output.put_line(my_cur%rowcount);
loop if my_cur%isopen then fetch my_cur into info;
exit when my_cur%notfound;
dbms_output.put_line(info。empno);
dbms_output.put_line(my_cur%rowcount);
end if;
end loop;
close my_cur;
end;
使用显示游标删除或更新
使用游标时,如果处理过程中需要删除或更新。
在定义游标查询语句时必须使用select..for update语句,而在执行delete或update时使用where current of子句指定游标当前行。
cursor cursor_name is select_statement for update[of column] wait/nowait
在使用for update 子句声明游标之后,可以使用以下语法更新行:
update table_name set column_name=column_value where current of cursor_name;
update命令中使用的列必须出现在for update of子句中select语句必须只包括一个表,而且delete和update语句只有在打开游标并且提取特定行之后才能使用。
declare cursor cur_emp is select * from emp where sal<2000 for update of sal;
num emp%rowtype;
begin open cur_emp;
loop fetch cur_emp into num;
exit when cur_emp%notfound;
update emp set sal=2000 where current of cur_emp;
end loop;
close cur_emp;
end;
带参数的显示游标 PL/SQL中允许显示游标接受输入参数。
用于声明带参数的显示游标语法
cursor cursor_name[<param_name> data_type] [return <return type>] is select_statement declare dept_num emp.deptno%type;
emp_num emp.empno%type;
emp_nam emp.ename%type;
cursor emp_cur(deptparam number) is select empno,ename from emp where deptno=deptparam;
begin dept_num:='&部门编号';
open emp_cur(dept_num);
loop fetch emp_cur into emp_num,emp_nam;
exit when emp_cur%notfound;
dbms_output.put_line(emp_num||' '||emp_nam);
end loop;
close emp_cur;
end;
可以使用循环游标来简化显示游标。
循环游标隐式打开显示游标(不需要open)自动从结果集提取记录,然后处理完所有记录自动关闭游标。
循环游标自动创建%rowtype类型的变量并将此变量用做记录的索引。
循环游标语法如下:
for record_index in cursor_name record_index是PL/SQL自动创建的变量,此变量的属性声明为%rowtype类型。
作用域for循环之内。循环游标的特性有:从游标中提取所有记录之后自动关闭游标。
提取和处理游标中每一条记录提取记录之后%notfound属性为true则退出循环。
如果未有结果集,则不进入循环。
declare cursor emp_cur is select * from emp;
begin for temp in emp_cur loop dbms_output.put_line(temp.ename);
end loop;
end;
循环游标自动打开,提取,关闭。只适用于静态游标
ref游标
隐式游标和显示游标都是静态定义的。
它们在编译的时候结果集就已经被确定。
如果想在运行的时候动态确定结果集,就要使用ref游标和游标变量。
创建ref游标需要两个步骤:
1 声明ref cursor类型
2 声明ref cursor类型变量
语法如下:
type ref_cursor_name is ref cursor [return record_type]
其中,return用于指定游标提取结果集的返回类型。
有return表示是强类型ref游标, 没有return表示是弱类型的游标。弱类型游标可以提取任何类型的结果集。
定义游标变量之后,就可以在PL/SQL执行部门打开游标变量 open cursor_name for select_statement;
declare type emp_cur is ref cursor;
my_cur emp_cur;
num number;
selection varchar(2):='&请输入编号';
begin
if selection='1' then dbms_output.put_line('员工信息');
open my_cur for select deptno from emp;
elsif selection='2'
then dbms_output.put_line('部门信息');
open my_cur for select deptno from dept;
else dbms_output.put_line('请输入员工信息(1)或门部信息(2)');
end if;
fetch my_cur into num;
while my_cur%found loop dbms_output.put_line(num);
fetch my_cur into num;
end loop;
close my_cur;
end;
在PL/SQL中可以执行动态SQL语句,execute immediate语句只能语句处理返回单行或没有返回的SQL语句,ref游标则可以处理返回结果集的动态SQL。
ref游标的声明方法与普通ref游标相同,只是在open时指定了动态SQL字符串。
open cursor_name for dynamic_select_string [using bind_argument_list] declare type sql_cur is ref cursor;
my_cur sql_cur;
emp_info emp%rowtype;
sql_string varchar2(100):='&请输入查询字符串';
begin open my_cur for sql_string;
loop fetch my_cur into emp_info;
exit when my_cur%notfound;
dbms_output.put_line(emp_info。ename);
end loop;
close my_cur;
end;
游标变量的特点:
(1)游标变量可以从不同的结果集中提取记录
(2)游标变量可以做为存储过程参数进行传递
(3)游标变量可以引用游标的所有属性
(4)游标变量可以进行赋值运算 使用游标变量也有一定的限制
(1)for update子句不能与游标变量一起使用
(2)不允许在程序包使用游标变量(可以声明游标类型)
(3)另一台服务器上的子过程不能接受游标变量参数
(4)不能将NULL值赋给游标变量
(5)游标变量不能使用比较运算符
(6)数据库中的列不能存储游标变量
总结:
(1)游标是使用在PL/SQL中,是用来查询数据,获取结果集的指针
(2)游标类型包括隐式游标,显示游标和ref游标
(3)游标属性包括%found,%notfound,%rowcount,%isopen
(4)PL/SQL自动定义隐式游标,以获取最近执行SQL语句信息
(5)循环游标简化处理游标中所有行的查询
(6)在声明ref游标时,不要将它与select语句相关联
相关文章推荐
- Oracle PLSQL Demo - 20.弱类型REF游标[没有指定查询类型,也不指定返回类型]
- 【Oracle】PL/SQL 显式游标、隐式游标、动态游标
- Oracle异常处理内容,隐式游标
- Oracle显式游标与隐式游标
- oracle 隐式游标,显示游标,游标循环,动态SELECT语句和动态游标、异常等
- ORACLE显示游标和隐式游标的区别
- Oracle 游标使用总结
- Oracle隐式游标小例子
- 关于oracle 与 mysql 的索引与隐式转换的总结
- Oracle游标创建和使用的语法和举例(显示和隐式游标)
- 从概念到示例—Oracle引用(REF)游标
- Oracle 11g Release 1 (11.1) 游标——SQL 游标(隐式)
- Oracle游标使用总结
- oracle中的游标 包 集合 的学习总结
- Oracle中隐式游标和显式游标的教训[同事的经历]
- Oracle游标使用总结
- oracle 游标变量ref cursor详解
- oracle 之游标 ref cursor的用法
- oracle 类型转换函数 & oracle 隐式转换规则总结
- Oracle动态sql返回游标(sys_refcursor)