游标(Cursor)的使用
以下示例使用oracle Scott用户的emp为例
游标分为隐式游标、显式游标和动态游标三种,通常指的是显式游标
显式游标:
显示游标定义方式:Cursor 游标名 Is select查询语句;
打开游标:Open 游标名;
取游标指向的数据:Fetch 游标名 Into 变量;
关闭游标:Close 游标名;
--例子1:使用游标
Create Or Replace Procedure p_cursor1
As
--定义游标cur_name
Cursor cur_name Is Select ename from emp;
--定义变量,用来保存游标指向的查询结果的一行(在该例子,一行就是1个名字)
v_name emp.ename%Type; --变量类型同emp表的ename列
Begin
--需要显式的打开和关闭游标
Open cur_name; --打开游标
Loop
--把游标指向的数据保存到v_name
Fetch cur_name Into v_name;
--当游标指向查询结果的最后1行以后,就退出循环
--游标%notfound 是游标的一个属性,是一个逻辑值,true代表已经使用游标遍历完查询结果的每一行
Exit When cur_name%Notfound;
--输出每一个员工名字
dbms_output.put_line('emp name is: ' || v_name);
End Loop;
--使用完之后要关闭游标
Close cur_name; --关闭游标
End;
--例子2:使用游标
Create Or Replace Procedure p_cursor1
As
Cursor cur_name Is Select ename,sal from emp;
v_name cur_name%Rowtype; --类型同游标指向的行类型
Begin
--需要显示的打开和关闭游标
Open cur_name; --打开游标
Loop
Fetch cur_name Into v_name;
Exit When cur_name%Notfound;
dbms_output.put_line('emp name is: ' || v_name.ename || ' sal: ' || v_name.sal);
End Loop;
Close cur_name; --关闭游标
End;
--例子3:使用游标
--将emp表的员工名和工资列保存到另一张表ebak中
Create Table ebak As Select ename,sal from emp Where 1=2;
Select * from ebak;
Create Or Replace Procedure p_cursor1
As
Cursor cur_name Is Select ename,sal from emp;
v_name cur_name%Rowtype;
Begin
--需要显示的打开和关闭游标
Open cur_name; --打开游标
Loop
Fetch cur_name Into v_name;
Exit When cur_name%Notfound;
Insert Into ebak Values(v_name.ename, v_name.sal);
End Loop;
Commit;
Close cur_name;
End;
--例子4:使用for循环来使用游标(这种情况不需要手动打开和关闭游标)
Create Or Replace Procedure p_cursor1
As
Cursor cur_name Is Select ename from emp;
v_name emp.ename%Type;
Begin
--不需要显式的打开和关闭游标
--Open cur_name; --打开游标在这里不需要
For v_name In cur_name Loop
dbms_output.put_line('emp name is: ' || v_name.ename);
End Loop;
--Close cur_name; --关闭游标在这里不需要
End;
隐式游标
select语句上使用显式游标,隐式游标主要用在 update Delete 语句上
隐式游标用关键字sql表示,有四个属性
Sql%Isopen 是否打开,永远为false
Sql%Found 影响到了记录(数据行)
Sql%Notfound 没有影响到记录
Sql%Rowcount 影响到的记录数
多条sql语句,隐式游标Sql永远执行的是最后一条sql语句的结果
Select * from emp e;
--例子1
Create Or Replace Procedure p_cursor1(pmr_empno Number)
As
Begin
Update Emp Set Ename = 'ChgALLEN' Where Empno = pmr_empno;
--判读游标是否打开
If Sql%Isopen Then
Dbms_Output.Put_Line('Openging');
Else
Dbms_Output.Put_Line('closing');
End If;
--判读游标是否指向有效数据
If Sql%Found Then
Dbms_Output.Put_Line('Haha,游标指向了有效行');
Else
Dbms_Output.Put_Line('Sorry');
End If;
If Sql%Notfound Then
Dbms_Output.Put_Line('Notfound,Sorry');
Else
Dbms_Output.Put_Line('Haha');
End If;
Dbms_Output.Put_Line(Sql%Rowcount);
End;
--例子2
Create Or Replace Procedure p_cursor1(pmr_deptno Number)
As
Begin
Update Emp Set Ename = 'ChgALLEN' Where deptno = pmr_deptno;
--判读游标是否打开
If Sql%Isopen Then
Dbms_Output.Put_Line('Openging');
Else
Dbms_Output.Put_Line('closing');
End If;
--判读游标是否指向有效数据
If Sql%Found Then
Dbms_Output.Put_Line('Haha,游标指向了有效行');
Else
Dbms_Output.Put_Line('Sorry');
End If;
If Sql%Notfound Then
Dbms_Output.Put_Line('Notfound,Sorry');
Else
Dbms_Output.Put_Line('Haha');
End If;
Dbms_Output.Put_Line(Sql%Rowcount);
End;