理解游标(2)游标的属性介绍及不同游标类别的案例演示
PL/SQL提供了六种游标属性:
begin
update t set name='f' where id=2;
dbms_output.put_line('rows selected: '||sql%rowcount);
end;
rows selected: 1
%ISOPEN如果游标是打开的就返回true;否则,返回false通常用在确保当发生异常情况后游标不会一直打开着而不关闭
我们可以在pl/sql中使用这些游标属性,但不能再sql语句中使用
要使用一个游标属性,只需要在游标名字或游标变量后面加上%就可以,比如:cursor_name%attribute_name
对于一个隐式游标,游标的名字固定就是“SQL”,比如SQL%FOUND
下面以t表为例,对各种游标类别作简单使用介绍
SQL> rollback; Rollback complete SQL> select * from t; ID NAME---------- -------------------- 1 a 2 b 3 c 4 d 5 e
① 隐式游标实例:
begin --执行DML操作 update t set name = 'ff' where id = 5; --判断是否有受影响行 if sql%found then --打印受影响行数 dbms_output.put_line('影响行数:' || sql%rowcount); end if; --判断是否没有受影响行 if sql%notfound then dbms_output.put_line('id为5的记录不存在'); end if; end;
② 无参显式游标实例:
declare --声明游标表变量并关联sql cursor rowList is select * from t; --声明行变量 --如果上面的查询语句只有一个查询字段,这里也可以使用正常的变量声明方式(v_rowValue varchar2(20);)。 rowValue t%rowtype;begin open rowList; --打开游标 --如果确定游标中只有一条记录的话,loop和end loop可以不写,而exit必须存在于游标循环内,所以也不需要写。 loop fetch rowList into rowValue; --取出游标内的值放到rowValue中 exit when rowList%notfound; --判断是否还存在记录,如果不存在终止游标 dbms_output.put_line(rowValue.name); --将取到的值打印,如果查询只有一个字段这里只需写变量名即可。 end loop; close rowList; --关闭游标end;
③ 有参显式游标实例:
declare --声明带参数的游标变量并关联sql,并将参数与sql进行关联 cursor rowList(c_name varchar2, c_id number) is select * from t where t.name = c_name and t.id = c_id; --声明行变量 --如果上面的查询语句只有一个查询字段,这里也可以使用正常的变量声明方式(v_rowValue varchar2(20);)。 rowValue t%rowtype;begin open rowList('Think', 1); --打开游标,并将参数给出 --如果确定由表中只有一条记录的话,loop和end loop可以不写,而exit必须存在于游标循环内,所以也不需要写。 loop fetch rowList into rowValue; --取出游标内的值放到rowValue中 exit when rowList%notfound;--判断是否还存在记录,如果不存在终止游标 dbms_output.put_line(rowValue.name); --将的到的值打印,如果查询只有一个字段这里只需写变量名即可。 end loop; close rowList; --关闭游标end;
④ 游标FOR循环实例:
游标FOR循环不需要手动进行打开和管理操作,全部由PL/SQL引擎进行管理
FOR oo in xx 等同于fetch xx into oo;
declare --声明游标变量并关联sql cursor rowList is select level a from dual connect by level <= 10;begin for rowValue in rowList loop --rowValue是每条记录不需要事先声明,rowList是集合中的所有记录 dbms_output.put_line(rowValue.a);--取出集合中的值进行打印 end loop;end;declarebegin --可以将select语句for xx in 内,无论传参或是嵌套更为方便简洁。 for rowValue in (select level a from dual connect by level <=10) loop for rv in (select name from t where t.id = rowValue.a) loop dbms_output.put_line(rv.name );--将取到的值打印。 end loop; end loop;end;--这种是最简单的游标declarebegin for rowValue in 1..10 loop dbms_output.put_line(rowValue);--将取到的值打印,如果查询只有一个字段这里只需写变量名即可。 end loop;end;
⑤ REF游标实例:
declare type cus_cur_type is ref cursor return t%rowtype; --强类型Ref游标,查询的sql必须返回t表类型 --type cus_cur_type is ref cursor;弱类型Ref游标,返回类型没有限制 rowList cus_cur_type; -- 声明游标变量 rowValue t%rowtype; --声明行变量begin open rowList for select * from t; --打开游标,并关联sql loop fetch rowList into rowValue; --按行取出数据 exit when rowList%notfound;--判断是否还存在记录,如果不存在终止游标 dbms_output.put_line(rowValue.name);--将取到的值打印,如果查询只有一个字段这里只需写变量名即可。 end loop; close rowList;--关闭游标end;