今天又学了一个新的概念Cursor
,即游标。
接上一篇,oracle存储过程—-存储过程执行简单的增删改查sql ,上一篇中,写到存储过程的查询sql
,当时在写到查询的时候,突然不知道怎么对查询结果是多条的数据,如何操做遍历呢。java
Cursor
)的定义与做用 游标是SQL的一个内存工做区,由系统或用户以变量的形式定义。游标的做用就是用于临时存储从数据库中提取的数据块。在某些状况下,须要把数据从存放在磁盘的表中调到计算机内存中进行处理,最后将处理结果显示出来或最终写回数据库。这样数据处理的速度才会提升,不然频繁的磁盘数据交换会下降效率。
不过我是新手,我理解的是,游标就像咱们查询数据返回的集合类型,好比List
,我就把它当作一个引用类型,它指向了内存区域中的数据结果集。web
Cursor
)的应用场景 就以我如今理解的来讲,游标既然像查询结果集list
,那使用cursor
的状况,确定会有下边这两种状况,才可能使用到cursor
:sql
Cursor
)的使用考虑 上边的两种状况,都会涉及到遍历数据(存储过程
里如何遍历数据,下一篇再写),因此游标的使用也须要注意:数据库
Cursor
)的类别 游标有两种,显示游标
和隐式游标
。oracle
隐式游标:
上一篇中用到的SELECT…INTO…查询语句,一次只能从数据库中提取一行数据,对于这种形式的查询和DML操做,系统都会使用一个隐式游标。
DML操做和单行SELECT语句会使用隐式游标,它们是: svg
(2018-08-19补充)固然,隐式游标还有一种写法,以下,并无定义游标:oop
create or replace procedure test_cryptic_procedure as begin for cryptic_rec in ( select * from ly_ds ) loop dbms_output.put_line('名称:'||cryptic_rec.ly_mc||' 年龄:'||cryptic_rec.ly_nl);
end loop;
end;
以下方式执行:学习
set serveroutput on;
begin test_cryptic_procedure;
end;
将会看到以下的结果:测试
匿名块已完成 名称:eee 年龄:23 名称:王五 年龄:22 名称:赵六六 年龄:29 名称:李四 年龄:20
提示一下:由于隐式游标默认打开游标,可是若是调用%ISOPEN
却返回false
。这个注意一下,若是还没懂%ISOPEN
啥意思,那暂且不要管这个提示了。fetch
显式游标:
显示游标还分为静态游标
和动态游标
。显示游标的写法会在存储过程当中定义Cursor
,而且通常都有固定的四个步骤:声明游标
、打开游标
、提取数据
、关闭游标
。显式游标打开后,必须显式地关闭。游标一旦关闭,游标占用的资源就被释放,游标变成无效,必须从新打开才能使用。
隐式游标其实默认已经打开游标,并在执行完成后关闭游标释放资源。
&ems;若是你想详细了解一下游标的概念
,我是参考了下边这两篇文章:
Cursor
)的例子 下边是我学习后写的第一个游标的例子。不像上边那个隐式游标的例子连游标都没有定义,下边这个是定义了游标,可是没有去打开,for
循环会默认打开游标的。
create or replace procedure test_select3_procedure (sex varchar) AS --游标的定义 Cursor test_cursor is select id,ly_mc,LY_NB,ly_nl from ly_ds where LY_NB=sex;
cur test_cursor%rowtype; --游标的类型,我理解相似于list的泛型
BEGIN
for cur in test_cursor loop
exit when test_cursor%notfound;
dbms_output.put_line('数据是:'||cur.id||'_'||cur.ly_mc||'_'||cur.LY_NB||'_'||cur.ly_nl);
end loop;
END;
上边,首先看Cursor test_cursor is
这一行,它的意思是定义一个游标,test_cursor
为你要定义的名字,而is
后边是一个sql,也就是说当前这个sql的查询结果,赋值给游标test_cursor
。
而后,往下,接着cur test_cursor%rowtype
,这个是定义了一个类型,而这个类型,便是游标test_cursor
的返回结果类型,类型的名字为cur
。有点相似于java语言
中List
集合中的一个泛型
。
另外,关于for
是一个循环的写法,for cur in test_cursor
,即,从游标test_cursor
中取出一个结果cur
。
还有,注意,loop
和end loop
这是一个循环的开始标志和结束标志,但它俩兄弟是一个很执着的循环,若是没有定义退出条件,永远不会退出的,因此在上边的循环里边,有了退出条件exit when test_cursor%notfound;
,即当游标test_cursor
中没有数据了,就退出循环。
固然loop
循环的退出,发生下边的状况,才能退出:
goto
标识。 最后,可能你们注意到,上边并无显示游标中必定有的四个步骤,
声明游标
、打开游标
、提取数据
、关闭游标
,那是由于for
循环这样的遍历会自动给咱们打开游标,并在结束后关闭游标,下边会学习其余的遍历方法,可是都没有for
这样智能,因此以为for
循环游标,是个很好的选择。
set serveroutput on;
execute test_select3_procedure('女');
会获得以下的遍历结果,正是我根据条件女
查询到的结果集。
PROCEDURE TEST_SELECT3_PROCEDURE 已编译 匿名块已完成 数据是:2_王五_女_22
数据是:3_赵六六_女_29
数据是:4_李四_女_20