想想上一篇博客好像发了还没几天,结果现在就已经月底了,忙碌的10月呀,忙碌的青春。。
暂时也没什么东西特别想写的其实,想想前两周在图书馆的时候看到本PL/SQL程序设计,简单看了下显式游标,根据自己日常的应用,弄几个简单的案例发一下,应该对Oracle的显式游标的有些帮助。
环境不想单独分点了,还是公司标配的联想thinkpad,win10,Oracle Database 11g r2,plsql12,谷歌浏览器,搜狗输入法。。
1、小技巧,也是看下面之前要知道的
1.1 dbms_output.put_line('输出内容');
虽然很多人应该都有在用,但还是说一下吧,这是Oracle自带的输出字符串的方法,下面截图说明一下效果。
1.1.1 在plsql 的 SQL窗口中
如下图,细心的小伙伴应该都有发现,SQL窗口左上角会有三个小标签页,默认显示的是SQL标签页,我们在SQL窗口运行下图1的代码的时候,就可以切换到输出窗口查看输出的结果。
1.1.2 在命令窗口中(sqlplus同理)
在命令窗口中,默认输出功能是关闭的,所以我们在一个命令窗口使用输出功能之前,需要先打开输出功能,然后再XXX,RT。但有个有意思的地方没搞清楚,命令应该是set serveroutput on,但是不知道为啥用set serverout on 也行,这里就不多说了。。。
1.2 connect by level <= num
这个涉及到Oracle的层级查询,说起来可能说到晚上9点都说不完,我就直接贴一下这次中用到的那句sql 的结果,,如下图的条件level <= 5就会产生一个 1~5 的序列,后面也将直接用这种sql来构造数据进行遍历
2、小小小案例
2.1 遍历输出
就按照上面的查询,定义一个游标,然后进行遍历,获取到每一行的值,进行输出
declare
cursor lr_num is --定义一个游标,名为:lr_num
select level lv
from dual
connect by level <= 5; --这段查询即为游标lr_num的具体内容
v_num lr_num%rowtype; --定义一个变量v_num,数据类型为游标 lr_num 的 %ROWTYPE,即lr_num的一行
begin
open lr_num; --打开游标lr_num
loop --开始循环
fetch lr_num into v_num; --把游标 lr_num 中的next一行数据 into 到变量 v_num 中
exit when lr_num%notfound; --如果 lr_num 中找不到next一行数据,即退出循环
dbms_output.put_line(v_num.lv); --输出 v_num 变量中的 lv 字段的值
end loop; --结束循环
close lr_num; --关闭游标
end;
/
执行后看下输出窗口:
上面是比较完整的遍历的过程,再说下用while循环和for循环遍历的方法,执行后输出的结果是一模一样的,就不截图了
--1.1 while循环实现(效果同上)
declare
cursor lr_num is
select level lv from dual connect by level <= 5;
v_num lr_num%rowtype;
begin
open lr_num; --打开游标
fetch lr_num into v_num; --取一条数据插入v_num
while lr_num%found loop --如果能取到数据,开始循环
dbms_output.put_line(v_num.lv); --输出取到的数据中的numer字段
fetch lr_num into v_num; --取出下一条数据插入v_num,然后循环上面部分
end loop; --结束循环
close lr_num; --关闭游标
end;
/
--1.2 for循环遍历游标的方法(效果同上)
declare
cursor lr_num is
select level lv from dual connect by level <= 5;
begin
for v_num in lr_num loop --开始循环,自动打开游标,并按行依次把数据赋给形参v_num,然后循环体里面就针对v_num进行操作即可
dbms_output.put_line(v_num.lv); --输出v_num中的numer
end loop; --遍历完游标后自动关闭游标并结束循环
end;
/
上面三种遍历方法,就易用程度来说肯定是for循环比较好,代码也短,理解也简单。所以后面我也直接用for循环演示啦
2.2 遍历求和
还是开始的那个游标内容,进行求和,思路就是遍历相加嘛,每次相加的值存到变量cnt中,,看代码,再看输出的结果
--2、遍历,累加
declare
cursor lr_num is
select level lv from dual connect by level <= 5;
cnt number(8) := 0 ; --累加值,初始化为0
begin
for v_num in lr_num loop
cnt := cnt + v_num.lv; --累加
dbms_output.put_line('当前数字为:' || v_num.lv || ', 累加结果为:' || cnt); --输出
end loop;
end ;
/
2.3 显式游标中变量的使用
像之前我们的游标都是写死level <= 5, 那游标的数据就是死数据,每次都是固定的数据。但如果想通过传递参数的方式去改变查询的条件,就可以像下面,定一个参数ln_num,然后查询中level <= ln_num,这样,每次打开游标调用查询的时候,ln_num的值就直接影响查询的结果,看代码及结果
--3、显式游标中的变量的使用
declare
ln_num number(8);
cursor lr_num is
select level lv from dual connect by level <= ln_num;
begin
--第一次,5条
ln_num := 5 ;
--此时打开游标,会执行游标的查询,此时ln_num为5,查到的结果即为5条
for v_num in lr_num loop
dbms_output.put_line('第1次遍历:' || v_num.lv);
end loop;
--第二次,7
ln_num := 7 ;
--此时打开游标,会执行游标的查询,此时ln_num为7,查到的结果即为7条
for v_num in lr_num loop
dbms_output.put_line('第2次遍历:' || v_num.lv);
end loop;
end ;
/
2.4 参数化显式游标
这个跟上面的其实贼像,都是通过外部参数来控制游标的查询条件,达到改变游标的查询结果的效果,但是参数化显式游标更像是传参,游标上会写一个形式参数,调用的时候通过这个往这个形式参数中传参,就类似调用函数时往函数里面传递参数,代码及效果如下:
--4、参数化显式游标
declare
cursor lr_num(an_num number default 3) is
select level lv from dual connect by level <= an_num;
v_num lr_num%rowtype;
begin
--第一次,默认,default为3
for v_num in lr_num loop
dbms_output.put_line('第1次遍历:' || v_num.lv);
end loop;
--第二次,传参指定,5条
for v_num in lr_num(5) loop
dbms_output.put_line('第2次遍历:' || v_num.lv);
end loop;
end ;
/
好了,就写这么多吧,10月没几天了,珍惜时间,早睡早起。11月见