1118-01 cursor 概念,经典例子
类型
1.隐式游标
2.显式游标
3.ref cursor
4.sysref cursorsql
定义
1.隐式游标
无需定义,select语句即为隐式游标session
2.显式游标
cursor <cursor>[(<param_list>)]is <select_statement>;
说明:
2.1 定义时不带参数,带参数
说明:
1)参数 只能指定 数据类型,不能指定长度。
2)参数能够用 default 设置默认值,设有默认值的游标在open时 能够 不带参数。
3)参数 一般用在 <select_statement> 中。
2.2 < select_statement >中 不带变量,带变量oop
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循环取值。fetch
4.sys_refcursorcode
属性(4个)
1.found
2.notfound
3.rowcount
4.isopen
引用方式:
显式游标:<cursor>%<游标属性>
隐式游标:SQL%<游标属性>server
注意:除了属性isopen外的其余3个属性 至少fetch一次,该属性才有值,即才能够使用。it
遍历游标:取游标中的值
1. fetch <cursor> into <column_variable_list>;
2. fetch <cursor> into <行类型变量|记录类型变量>
说明:
<record> --记录类型 的 显示定义
<table>%rowtype -- 记录类型 的 隐式定义
<view>%rowtype -- 记录类型 的 隐式定义
<cursor>%rowtype -- 记录类型 的 游标定义
使用 <记录类型>.<column>取得行中列的值。
3. for循环中能够使用 循环计数变量.字段名io
游标的使用流程:
1.定义
2.open
3.fetch
4.close
说明:for循环中,无需手动open,fetch,close。for循环
例1.显式游标的定义(无参,有参,带变量,不带变量)table
例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;/