光标:
就是一个结果集(Result Set)
光标的语法:
cursor 光标名 [(参数名 数据类型[,参数名 数据类型]...)]
is select 语句;
一个具体的光标
cursor c1 is select ename from emp;
从光标中取值:
打开光标
open c1; (打开光标执行查询)
取一行光标的值:
fetch c1 into pename;(取一行到变量中)
关闭光标:
close c1;(关闭游标释放资源)
使用光标查询员工姓名和工资,并打印:
--查询并打印员工的姓名和薪水
/*
1.光标的属性
%found %notfound
*/
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;
--思考:1.循环什么时候退出? 2.fetch不一定能取到记录
--exit when 没有取到记录
exit when cemp%notfound;
--打印
dbms_output.put_line(pename||'的薪水是'||psal);
end loop;
--关闭光标
close cemp;
end;
/
按员工的职位长工资,总裁涨1000元,经理涨800元,其他员工涨400元。
--给员工涨工资,总裁1000,经理800,其他400
set serveroutput on
declare
--定义光标代表给那些员工涨工资
--alter table emp rename column "JOB" to empjob
cursor cemp is select empno,empjob from emp;
pempno emp.empno%type;
pjob emp.empjob%type;
begin
--打开光标
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;
/
光标的属性和光标的限制:
/*
1.光标的属性
%found %notfound
%isopen:判断光标是否打开
%rowcount:影响的行数
2.光标数的限制
*/
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;
/
/*
1.光标的属性
%found %notfound
%isopen:判断光标是否打开
%rowcount:影响的行数
2.光标数的限制:默认情况下,Oracle数据库只允许在同一个会话中,打开300个光标
SQL> show parameter cursor
NAME TYPE VALUE
------------------------------------ ----------- -----------
cursor_bind_capture_destination string memory+disk
cursor_sharing string EXACT
cursor_space_for_time boolean FALSE
open_cursors integer 300
session_cached_cursors integer 50
修改光标数的限制:
alter system set open_cursors=400 scope=both;
scope的取值:both,memory,spfile(数据库需要重启)
SQL> alter system set open_cursors=400 scope=both;
系统已更改。
SQL> show parameter cursor
NAME TYPE VALUE
------------------------------------ ----------- -----------
cursor_bind_capture_destination string memory+disk
cursor_sharing string EXACT
cursor_space_for_time boolean FALSE
open_cursors integer 400
session_cached_cursors integer 50
*/
set serveroutput on
declare
--定义光标
cursor cemp is select empno,empjob from emp;
pempno emp.empno%type;
pjob emp.empjob%type;
begin
--打开光标
open cemp;
loop
--取出一条记录
fetch cemp into pempno,pjob;
exit when cemp%notfound;
--打印rowcount的值
dbms_output.put_line('rowcount:'||cemp%rowcount);
end loop;
--关闭光标
close cemp;
end;
/
带参数的光标:
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%notfound;
dbms_output.put_line(pename);
end loop;
--关闭光标
close cemp;
end;
/