greenZ

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1118-01 cursor 概念,经典例子
类型
1.隐式游标
2.显式游标
3.ref cursor
4.sysref cursor

定义
1.隐式游标
无需定义,select语句即为隐式游标

2.显式游标
cursor <cursor>[(<param_list>)]is <select_statement>;
说明:
2.1 定义时不带参数,带参数
说明:
1)参数 只能指定 数据类型,不能指定长度。
2)参数可以用 default 设置默认值,设有默认值的游标在open时 可以 不带参数。
3)参数 通常用在 <select_statement> 中。
2.2 < select_statement >中 不带变量,带变量

3.ref cursor
3.1弱类型
type <cursor> is ref cursor;
3.2强类型
type <cursor> is ref cursor return tab_student%rowtype; --指定了return
注意:
1)创建procedure返回游标类型变量(out 参数)时,只能使用 ref cursor。
2)ref cursor没有参数,可以使用带变量的sql实现。
3)ref cursor在open时有2种写法:
open <ref_cursor> for <select_statement>;
open <ref_cursor> for <vv_sql>;
而显式游标的定义 只能用 is <select_statement>
4)因为ref cursor 的具体sql语句在open时指定,所以 ref cursor 不可以使用 for循环取值。

4.sys_refcursor


属性(4个)
1.found
2.notfound
3.rowcount
4.isopen
引用方式:
显式游标:<cursor>%<游标属性>
隐式游标:SQL%<游标属性>

注意:除了属性isopen外的其他3个属性 至少fetch一次,该属性才有值,即才可以使用。


遍历游标:取游标中的值
1. fetch <cursor> into <column_variable_list>;
2. fetch <cursor> into <行类型变量|记录类型变量>
说明:
<record> --记录类型 的 显示定义
<table>%rowtype -- 记录类型 的 隐式定义
<view>%rowtype -- 记录类型 的 隐式定义
<cursor>%rowtype -- 记录类型 的 游标定义
使用 <记录类型>.<column>取得行中列的值。
3. for循环中可以使用 循环计数变量.字段名


游标的使用流程:
1.定义
2.open
3.fetch
4.close
说明:for循环中,无需手动open,fetch,close。

 

 

例1.显式游标的定义(无参,有参,带变量,不带变量)

例2.游标属性(隐式,显式)

例3.显示游标的使用(遍历,取值)

例4.ref cursor的定义,使用
说明:
ref cursor定义与打开:定义用关键字type(显式游标的定义使用关键字 cursor);open时用关键字for指定SQL。
ref cursor的遍历,取值:与 显式游标 相同。


经典例子:
1.需求:按部门加薪
员工表,如果是10部门,员工加薪¥100;20部门,员工加薪¥200;30部门,员工加薪¥300。

set serveroutput on;

declare
cursor vc_emp(vp_emp_depart integer) is
select emp_id,emp_name,emp_depart,emp_salary from t_emp where emp_depart = vp_emp_depart;
begin
for i in 1..3 loop
for i_emp in vc_emp(i*10) loop
update t_emp set emp_salary=i_emp.salary*i*100 where emp_id = i_emp.emp_id;
end loop;
end loop;
commit;
exception
when others then
rollback;
dbms_output.put_line(sqlcode||','||substr(sqlerrm,1,200));
end;
/

 

2.需求:
存储过程返回ref cursor
调用存储过程,并遍历其返回的游标
alter session set plsql_warnings = 'enable:all';
set serveroutput on;

--定义包
create or replace package pkg_cur as
type lax_cursor is ref cursor; --弱类型
type strict_cursor is ref cursor return t_student%rowtype; --强类型
end pkg_cur;
/

show errors;

--定义存储过程
create or replace procedure prc_cur(
ii_sid in integer,
oc_cur out pkg_cur.lax_cursor
)
is
begin
open oc_cur for
select sid,name,age,gender from t_student where sid <= ii_sid;
exception
when others then
dbms_output.put_line(sqlcode||','||substr(sqlerrm,1,200));
end prc_cur;
/

--调用
set serveroutput on;
declare
vi_sid integer;
vc_cur pkg_cur.lax_cursor;
vt_table t_student%rowtype;
begin
v_sid := 2;
prc_cur(vi_sid,vc_cur);
if (vc_cur%isopen) then
dbms_output.put_line('vc_cur is opened.');
loop
fetch vc_cur into vt_table;
exit when vc_cur%notfound;
dbms_output.put_line(vt_table.sid||','||vt_table.name||','||vt_table.age||','||vt_table.gender);
end loop;
end if;
end;
/

posted on 2018-04-05 12:00  绿Z  阅读(1876)  评论(0编辑  收藏  举报