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循环是用来循环游标的最好方法。高效,简洁,安全。
但遗憾的是,常常见到的却是第一种方法。所以从今之后得改变这个习惯了。
分享到:
相关推荐
1. **游标的使用流程**:在存储过程中使用游标的标准流程包括声明游标、打开游标、读取数据以及关闭游标。因此,完整的步骤顺序是:声明 --> 打开 --> 读取 --> 关闭。 ### Windows 98 资源管理器的文件选择 1. **...
17. 游标操作流程:在存储过程中,使用游标通常包括声明、打开、读取和关闭四个步骤。 18. OSI参考模型:OSI模型的最低层是物理层,负责数据的物理传输。 19. SQL日期查询:在SQL中,限定2003年参加工作职工的时间...
在数据库管理中尤为重要,用于描述用户如何与存储的数据交互。 #### 3. 实现(Achieve) 实现可以指在编程或系统设计过程中将理论模型转化为实际工作系统的步骤。 #### 4. 获取(Acquire) 获取是指获取资源或权限...
游标(cursor)在数据库中用于跟踪位置,循环冗余检验(cyclic redundancy check)是数据校验的一种方法。 数据库的完整性(database: integrity)确保数据的准确性和一致性(database: consistency),可恢复性(database: ...
2. **Adjacency List Method**:邻接表表示法,一种图形数据结构,用于存储图中的边,其中每个顶点的邻接顶点列表被存储。 3. **Adjacency Matrix Method**:邻接矩阵表示法,另一种图形数据结构,用二维数组表示图...
16、在JAVA 中,如何跳出当前的多重嵌套循环? 9 17、构造器Constructor 是否可被override? 9 18、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对? 9 19、是否可以继承String 类? 9 ...
4. **函数与方法**:Function、Method是程序中的可重用代码块,它们接收参数(Parameter),并可能返回值(Return Value)。 5. **类与对象**:面向对象编程(Object-Oriented Programming)中的类(Class)、对象...
- **变量**:在Python中,变量用于存储数据值。例如,`name = 'woniu'`。 - **逻辑判断**:通过`if`语句来实现条件判断。如示例中的`if name == 'woniu':`。 - **循环**:使用`for`或`while`循环来重复执行代码块。...