光標就是一個結果集(Result Set)
一、光標的語法
CURSOR 光標名 [(參數名 數據類型[, 參數名 數據類型])]
IS SELECT 語句;
例:cursor c1 is select ename from emp;
二、從光標中取值
1、打開光標
- open c1; (打開光標執行查詢)
2、取一行光標的值:
- fetch c1 into pename; (取一行到變量中)
fetch的作用:- 把當前指針指向的記錄返回
- 將指針指向下一條記錄
3、關閉光標
- close c1; (關閉光標釋放資源)
三、光標的具體案例
1、使用光標查詢員工姓名和工資,並打印
--查詢並打印員工的姓名和薪水
/*
1、光標的屬性
&found ¬found
*/
set serveroutput on
declare
--定義一個光標
cursor cemp is select ename,sal from emp;
--爲光標定義對應的變量
pename emp.ename%type;
psal emp.sal%type;
begin
--打開光標
open cemp;
loop
--取一條記錄
fetch cemp into pename, psal;
exit when cemp%notfound;
dbms_output.put_line(pename||'的薪水是'||psal);
end loop;
--關閉光標
close cemp;
end;
/
2、按員工的職位漲工資,總裁漲1000元,經理漲800元,其他人員漲400元。
--給員工漲工資,總裁1000,經理800,其他400
set serveroutput on
declare
--定義光標代表給哪些員工漲工資
--alter table "C##SCOTT"."EMP" rename column "JOB" to empjob
cursor cemp is select empno, empjob from emp;
pempno emp.empno%type;
pjob emp.empjob%type;
begin
--rollback;
--打開光標
open cemp;
loop
--取出一個員工
fetch cemp into pempno,pjob;
exit when cemp%notfound;
--判斷員工的職位
if pjob = 'PRESIDENT' then update emp set sal = sal+1000 where empno=pempno;
elsif pjob = 'MANAGER' then update emp set sal = sal+800 where empno=pempno;
else update emp set sal=sal+400 where empno = pempno;
end if;
end loop;
--關閉光標
close cemp;
--對於oracle, 默認的事務隔離級別是read committed
--事務的ACID
commit;
dbms_output.put_line('漲工資完成');
end;
/
四、光標的屬性
%found %notfound
%isopen
判斷光標是否打開
%rowcount
影響的行數
set serveroutput on
declare
cursor cemp is select empno, empjob from emp;
pempno emp.empno%type;
pjob emp.empjob%type;
begin
--打開光標
open cemp;
if cemp%isopen then
dbms_output.put_line('光標已經打開');
else
dbms_output.put_line('光標沒有打開');
end if;
--關閉光標
close cemp ;
end;
/
set serveroutput on
declare
cursor cemp is select empno, empjob from emp;
pempno emp.empnootype;
pjob emp.empjobatype;
begin
--打開光標
open cemp;
loop
--取出一條記錄
fetch cemp into pempno, pjob;
exit when cemp¬found;
dbms_output.put_line('rowcount:'|| cemp&rowcount);
end loop;
--關閉光標.
close cemp;
end;
/
五、光標的限制
默認情況下,oracle數據庫只允許在同一個會話中,打開300個光標
修改光標數的限制:
alter system set open_cursors=400 scope=both;
scope的取值:both(當前實例、參數文件 同時更改),
memory(只更改當前實例,不更改參數文件),
spfile(只更改參數文件,不更改當前實例,數據庫需要重啓)
六、帶參數的光標
CURSOR 光標名 [(參數名 數據類型[, 參數名 數據類型])]
IS SELECT 語句;
例:查詢某個部門中員工的姓名
set serveroutput on
declare
cursor cemp(dno number) is select ename from emp where deptno=dno;
pename emp.ename%type;
begin
--打開光標
open cemp(10);
loop
--取出一條記錄
fetch cemp into pename;
exit when cemp¬found;
dbms_output.put_line(pename);
end loop;
--關閉光標
close cemp;
end;
/