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;
/