PL/SQL程序设计-学习笔记3--游标

四、游标的使用
在PL/SQL程序中,对于处理多行记录的事务经常使用游标来实现。
游标是一个指向上下文的句柄(handle)或指针。通过游标,PL/SQL可以控制上下文区和处理语句时上下文区会发生些什么事情。
游标属性:%FOUND(布尔型属性,当最后一次读记录时成功返回,则值为true) %NOTFOUND(布尔型属性,与%FOUND相反) %ISOPEN(布尔型属性,当游标已打开时返回true) %ROWCOUNT(数字型属性,返回已从游标中读取的记录数)
declare
--定义游标
cursor c_cursor(emp_no number default 11) is
select last_name,salary from employees where rownum < emp_no order by salary;
v_name employees.last_name%type;
v_sal employees.salary%type;
begin
--打开游标
open c_cursor(emp_no => 20);
--提取游标数据
fetch c_cursor into v_name,v_sal;
while c_cursor %found loop
dbms_output.put_line(v_name || ':' || v_sal);
fetch c_cursor into v_name,v_sal;
end loop;
--关闭游标
close c_cursor;
end;
游标的FOR循环:PL/SQL语言提高了游标FOR循环语句,自动执行游标的OPEN、FETCH、CLOSE语句和循环语句的功能。
declare
cursor c_emp(dep_id number default 50) is
select last_name,salary sal from employees where department_id = dep_id;
begin
for v_emp in c_emp(80) loop
dbms_output.put_line(v_emp.last_name || ',' || v_emp.sal);
end loop;
end;
PL/SQL还允许在游标FOR循环语句中使用子查询来实现游标的功能:
begin
for v_emp in (select last_name,salary from employees) loop
dbms_output.put_line(v_emp.last_name ||','|| v_emp.salary);
end loop;
end;
显示游标主要是用于对查询语句的处理,尤其是在查询结果为多条记录的情况下;而对于非查询语句,如修改、删除操作,则由ORACLE系统自动的为这些操作设置游标并创建其工作区,这些有系统隐含创建的游标称为隐式游标,隐式游标的名字为SQL.
隐式游标属性:SQL%FOUND / SQL%NOTFOUND / SQL%ROWCOUNT / SQL%ISOPEN
declare
v_name employees.last_name%type;
v_id employees.employee_id%type := &v_id;
begin
update employees set last_name = 'xx' where employee_id = v_id;
if SQL%NOTFOUND then
dbms_output.put_line('查无此人');
end if;
end;
SELECT ...INTO语句触发NO_DATA_FOUND;
当一个显示游标的WHERE子句未找到时触发%NOTFOUND;
当UPDATE或DELETE语句的WHERE子句未找到时触发SQL%NOTFOUND;
在提取循环中要用%NOTFOUND或%FOUND来确定循环的退出条件,不要用NO_DATA_FOUND.
游标修改和删除操作:是指在游标定位下,修改或删除表中指定的数据行。但要求游标查询语句中必须使用FOR UPDATE选项,以便在打开游标时锁定游标结果集合在表中对应数据行的所有列和部分列。
为了对正在处理(查询)的行不被另外的用户改动,ORACLE提供了一个FOR UPDATE子句来对所选择的行进行锁住。该需求迫使ORACLE锁定游标结果集合的行,可以防止其他事务处理更新或删除相同的行,直到您的事务处理提交或回退为止。
declare
v_dep_id employees.department_id%type := &v_dep_id;
cursor emp_cursor is
select last_name,salary from employees where department_id = v_dep_id for update nowait;
begin
for emp_rec in emp_cursor loop
if emp_rec.salary < 3000 then
update employees set salary = 3000 where current of emp_cursor;
end if;
end loop;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值