在PL/SQL中游标被分为隐式和显式两种,其中显式的cursor是我们最常见的一种,下面简单记录一下各种游标的使用方法:
1.显式游标
一般来说普通的显示游标,是通过定义来获得的,一般的流程就是open,fetch,close等方法来对我们的cursor进行基本的操作
首先来看最common的一种使用方法:
declare
cursor mycur is select last_name from alan;
l_name varchar2(50);
begin
open mycur;
loop
fetch mycur into l_name;
exit when mycur%notfound;
dbms_output.put_line(l_name);
end loop;
close mycur;
end;
/
上面的SP效率明显不高,需要fetch游标多次才可以完成工作,那么相对于这种情况。对于显示游标我们还可以利用bulk collect的方式来批量获取游标中的内容。目标变量一定要是
table类型的,也就是我们通常所说的container类型。
如果不加limit限制,默认情况下会将游标里的所有内容放到container中。
下面的SP并没有加loop,而是一次fetch游标中的内容,并通过l_name.count,取出数据。
declare
cursor mycur is select last_name from alan;
l_name dbms_sql.varchar2_table;
-- type type_l_name is table of alan.last_name%type;
-- l_name type_l_name;
begin
open mycur;
fetch mycur bulk collect into l_name;
for i in 1 .. l_name.count
loop
dbms_output.put_line(l_name(i));
end loop;
close mycur;
end;
/
那么对于bulk collect方式还可以对其的fetch范围加limit限制
declare
cursor mycur is select last_name from alan;
l_name dbms_sql.varchar2_table;
begin
open mycur;
loop
fetch mycur bulk collect into l_name limit 15;
exit when mycur%notfound;
for i in 1 .. l_name.count
loop
dbms_output.put_line(l_name(i));
end loop;
end loop;
close mycur;
end;
/
限制一次fetch 15行的数据到游标中,然后分批获取数据。
2.隐式游标
和显示不同,在使用的时候不需要open,fetch,close游标的这些动作:
其实最常见的select .. into方式就是declare了一个隐式的游标
declare
l_name varchar2(50);
begin
select last_name into l_name from alan where rownum < 2;
dbms_output.put_line(l_name);
end;
/
以下是动态
SQL的一些隐式游标的例子:
首先简单说明一下动态SQL,在Oracle PL/SQL中,SQL语句可以分为动态SQL和静态SQL,对于静态的SQL,在编译和开发过程中SQL语句中所引用的对象或者是变量一定是确定的,也就是说Oracle要在编译前前期绑定这些变量。静态SQL语句执行的时候是需要确定的对象。动态SQL就是指PL/SQL在编译的时候SQL中引用的变量或者是对象等等是不确定的,那么这个时候在编译的时候我们就可以跳过这块区域,在程序运行的时候进行变量和对象的后期绑定。因此通过动态SQL呢,我们就可以执行诸如DDL等静态SQL所不能实现的功能了。
declare
l_name varchar2(50);
l_tab_name varchar2(50);
l_sql varchar2(300);
begin
l_tab_name := 'ALAN';
l_sql := 'select last_name from '||l_tab_name||' where rownum = 1';
execute immediate l_sql into l_name;
dbms_output.put_line(l_name);
end;
/
declare
l_name_array dbms_sql.varchar2_table;
l_tab_name varchar2(50);
l_sql varchar2(300);
begin
l_tab_name := 'ALAN';
l_sql := 'select last_name from '||l_tab_name;
execute immediate l_sql bulk collect into l_name_array;
for i in 1 .. l_name_array.count
loop
dbms_output.put_line(l_name_array(i));
end loop;
end;
/
for类型的隐式游标
begin
for mycur in (select last_name from alan)
loop
dbms_output.put_line(mycur.last_name);
end loop;
end;
/