3.2 选用何种游标?
显示游标分为:普通游标,参数化游标和游标变量三种。
下面以一个过程来进行说明
- create or replace procedure proccursor(p varchar2)
- as
-
v_rownum number(10) := 1;
-
cursor c_postype is select pos_type from pos_type_tbl where rownum =1;
- cursor c_postype1 is select pos_type from pos_type_tbl where rownum = v_rownum;
- cursor c_postype2(p_rownum number) is select pos_type from pos_type_tbl where rownum = p_rownum;
- type t_postype is ref cursor ;
- c_postype3 t_postype;
-
v_postype varchar2(20);
- begin
- open c_postype;
- fetch c_postype into v_postype;
- dbms_output.put_line(v_postype);
- close c_postype;
- open c_postype1;
- fetch c_postype1 into v_postype;
- dbms_output.put_line(v_postype);
- close c_postype1;
-
open c_postype2(1);
- fetch c_postype2 into v_postype;
- dbms_output.put_line(v_postype);
- close c_postype2;
-
open c_postype3 for select pos_type from pos_type_tbl where rownum =1;
- fetch c_postype3 into v_postype;
- dbms_output.put_line(v_postype);
- close c_postype3;
- end;
cursor c_postype is select pos_type from pos_type_tbl where rownum =1
这一句是定义了一个最普通的游标,把整个查询已经写死,调用时不可以作任何改变。
cursor c_postype1 is select pos_type from pos_type_tbl where rownum = v_rownum;
这一句并没有写死,查询参数由变量v_rownum来决定。需要注意的是v_rownum必须在这个游标定义之前声明。
cursor c_postype2(p_rownum number) is select pos_type from pos_type_tbl where rownum = p_rownum;
这一条语句与第二条作用相似,都是可以为游标实现动态的查询。但是它进一步的缩小了参数的作用域范围。但是可读性降低了不少。
type t_postype is ref cursor ;
c_postype3 t_postype;
先定义了一个引用游标类型,然后再声明了一个游标变量。
open c_postype3 for select pos_type from pos_type_tbl where rownum =1;
然后再用open for 来打开一个查询。需要注意的是它可以多次使用,用来打开不同的查询。
从动态性来说,游标变量是最好用的,但是阅读性也是最差的。
注意,游标的定义只能用使关键字IS,它与AS不通用。
3.3 游标循环最佳策略
我们在进行PL/SQL编程时,经常需要循环读取结果集的数据。进行逐行处理,这个过程就需要对游标进行循环。对游标进行循环的方法有多种,我们在此一一分析。
- create or replace procedure proccycle(p varchar2)
- as
-
cursor c_postype is select pos_type, description from pos_type_tbl where rownum < 6;
-
v_postype varchar2(20);
-
v_description varchar2(50);
- begin
- open c_postype;
-
if c_postype%found then
-
dbms_output.put_line('found true');
-
elsif c_postype%found = false then
-
dbms_output.put_line('found false');
-
else
-
dbms_output.put_line('found null');
-
end if;
- loop
- fetch c_postype into v_postype,v_description ;
- exit when c_postype%notfound;
-
dbms_output.put_line('postype:'||v_postype||',description:'||v_description);
- end loop;
- close c_postype;
-
dbms_output.put_line('---loop end---');
- open c_postype;
- fetch c_postype into v_postype,v_description;
-
while c_postype%found loop
-
dbms_output.put_line('postype:'||v_postype||',description:'||v_description);
- fetch c_postype into v_postype,v_description ;
- end loop;
-
- close c_postype;
-
dbms_output.put_line('---while end---');
-
for v_pos in c_postype loop
- v_postype := v_pos.pos_type;
- v_description := v_pos.description;
-
dbms_output.put_line('postype:'||v_postype||',description:'||v_description);
- end loop;
-
dbms_output.put_line('---for end---');
- end;
使用游标之前需要开打游标,open cursor,循环完后再关闭游标close cursor.
这是使用游标应该慎记于心的法则。
上面的过程演示了游标循环的三种方法。
在讨论循环方法之前,我们先看看%found和%notfound这些游标的属性。
- open c_postype;
-
if c_postype%found then
-
dbms_output.put_line('found true');
-
elsif c_postype%found = false then
-
dbms_output.put_line('found false');
-
else
-
dbms_output.put_line('found null');
-
end if;
在打开一个游标之后,马上检查它的%found或%notfound属性,它得到的结果即不是true也不是false.而是null.必须执行一条fetch语句后,这些属性才有值。
第一种使用loop 循环
- loop
- fetch c_postype into v_postype,v_description ;
- exit when c_postype%notfound;
- ……
- end loop
这里需要注意,exit when语句一定要紧跟在fetch之后。必避免多余的数据处理。
处理逻辑需要跟在exit when之后。这一点需要多加小心。
循环结束后要记得关闭游标。
第二种使用while循环。
- fetch c_postype into v_postype,v_description;
-
while c_postype%found loop
- ……
- fetch c_postype into v_postype,v_description ;
- end loop;
我们知道了一个游标打开后,必须执行一次fetch语句,游标的属性才会起作用。所以使用while 循环时,就需要在循环之前进行一次fetch动作。
而且数据处理动作必须放在循环体内的fetch方法之前。循环体内的fetch方法要放在最后。否则就会多处理一次。这一点也要非常的小心。
总之,使用while来循环处理游标是最复杂的方法。
第三种 for循环
- for v_pos in c_postype loop
- v_postype := v_pos.pos_type;
- v_description := v_pos.description;
- …
- end loop;
可见for循环是比较简单实用的方法。
首先,它会自动open和close游标。解决了你忘记打开或关闭游标的烦恼。
其它,自动定义了一个记录类型及声明该类型的变量,并自动fetch数据到这个变量中。
我们需要注意v_pos 这个变量无需要在循环外进行声明,无需要为其指定数据类型。
它应该是一个记录类型,具体的结构是由游标决定的。
这个变量的作用域仅仅是在循环体内。
把v_pos看作一个记录变量就可以了,如果要获得某一个值就像调用记录一样就可以了。
如v_pos.pos_type
由此可见,for循环是用来循环游标的最好方法。高效,简洁,安全。
但遗憾的是,常常见到的却是第一种方法。所以从今之后得改变这个习惯了。
分享到:
相关推荐
python学习资源
jfinal-undertow 用于开发、部署由 jfinal 开发的 web 项目
基于Andorid的音乐播放器项目设计(国外开源)实现源码,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。
python学习资源
python学习资源
python学习一些项目和资源
【毕业设计】java-springboot+vue家具销售平台实现源码(完整前后端+mysql+说明文档+LunW).zip
HTML+CSS+JavaScarip开发的前端网页源代码
python学习资源
【毕业设计】java-springboot-vue健身房信息管理系统源码(完整前后端+mysql+说明文档+LunW).zip
成绩管理系统C/Go。大学生期末小作业,指针实现,C语言版本(ANSI C)和Go语言版本
1_基于大数据的智能菜品个性化推荐与点餐系统的设计与实现.docx
【毕业设计】java-springboot-vue交流互动平台实现源码(完整前后端+mysql+说明文档+LunW).zip
内容概要:本文主要探讨了在高并发情况下如何设计并优化火车票秒杀系统,确保系统的高性能与稳定性。通过对比分析三种库存管理模式(下单减库存、支付减库存、预扣库存),强调了预扣库存结合本地缓存及远程Redis统一库存的优势,同时介绍了如何利用Nginx的加权轮询策略、MQ消息队列异步处理等方式降低系统压力,保障交易完整性和数据一致性,防止超卖现象。 适用人群:具有一定互联网应用开发经验的研发人员和技术管理人员。 使用场景及目标:适用于电商、票务等行业需要处理大量瞬时并发请求的业务场景。其目标在于通过合理的架构规划,实现在高峰期保持平台的稳定运行,保证用户体验的同时最大化销售额。 其他说明:文中提及的技术细节如Epoll I/O多路复用模型以及分布式系统中的容错措施等内容,对于深入理解大规模并发系统的构建有着重要指导意义。
基于 OpenCV 和 PyTorch 的深度车牌识别
【毕业设计-java】springboot-vue教学资料管理系统实现源码(完整前后端+mysql+说明文档+LunW).zip
此数据集包含有关出租车行程的详细信息,包括乘客人数、行程距离、付款类型、车费金额和行程时长。它可用于各种数据分析和机器学习应用程序,例如票价预测和乘车模式分析。
把代码放到Word中,通过开发工具——Visual Basic——插入模块,粘贴在里在,把在硅基流动中申请的API放到VBA代码中。在Word中,选择一个问题,运行这个DeepSeekV3的宏就可以实现在线问答
【毕业设计】java-springboot+vue机动车号牌管理系统实现源码(完整前后端+mysql+说明文档+LunW).zip
【毕业设计】java-springboot-vue交通管理在线服务系统的开发源码(完整前后端+mysql+说明文档+LunW).zip