游标
来源:互联网 发布:c 低级编程 编辑:程序博客网 时间:2024/06/04 20:45
参考: http://www.cnblogs.com/sc-xx/archive/2011/12/03/2275084.html
PL/SQL中游标分为两类:
显式游标:由用户定义、操作,用于返回多行数据的select查询。
隐式游标:由系统自动进行操作,用于处理DML语句和返回单行数据的select查询。
显式游标有下列四个属性。
(1)%ISOPEN
(2)%FOUND
(3)%NOTFOUND
(4)%ROWCOUNT1. 游标声明
CURSOR cursor_name IS select_statement
2. 显式游标检索
2.1 简单循环检索游标 exit ... when cursor_name%NOTFOUND
-- fetch...into... exit when cursor_name%notfound declare cursor c_user is select cust_no,cust_nm,cust_type from zct_customer where rownum<10; c_row c_user%rowtype; begin open c_user; loop fetch c_user into c_row; exit when c_user%notfound; dbms_output.put_line(c_row.cust_nm||'-'||c_row.cust_no); end loop; close c_user; end;
2.2 while循环检索游标 while cursor_name%FOUND LOOP
-- while declare cursor c_user is select cust_no,cust_nm,cust_type from zct_customer where rownum<10; c_row c_user%rowtype; begin open c_user; fetch c_user into c_row; while c_user%found loop dbms_output.put_line(c_row.cust_nm||'-'||c_row.cust_no||'-'||c_row.cust_type); fetch c_user into c_row; end loop; close c_user; end;
2.3 for循环检索游标 for loop_variable in cursor_name LOOP
-- for ... in declare cursor c_user is select cust_no,cust_nm,cust_type from zct_customer where rownum<10; c_row c_user%rowtype; begin for c_row in c_user loop dbms_output.put_line(c_row.cust_nm||'-'||c_row.cust_no); end loop; end;
3. 游标更新或删除数据
如果要利用游标更新或删除数据,需要在游标定义中使用 for update子句,对要修改或删除的数据加锁。语法:
cursor cursor_name is
select select_list_item from table for update;
若定义游标使用 for update子句,则在执行时,可以在update语句或delete语句中使用 where current of 子句,以修改或删除由表中当前行所对应的数据库中的数据,
语法为:
where current of cursor_name;
注意:如果游标定义时没有使用 for update子句,则不能用游标修改或者删除数据库中的数据。
declare cursor c_emp is select * from emp where ENAME LIKE 'A%' OR ENAME LIKE 'S%' for update; v_increment number; v_emp c_emp%rowtype;begin for v_emp in c_emp loop dbms_output.put_line(r_AddSal.ENAME||'原来的工资:'||r_AddSal.SAL); case v_emp.deptno when 10 then v_increment := 100; when 20 then v_increment := 200; when 30 then v_increment := 300; else v_increment := 80; end case; UPDATE emp SET SAL=v_increment WHERE CURRENT OF c_emp; end loop;end;
注意:由于commit 语句会释放会话拥有的任和锁,因此如果在检索游标的循环内使用 commit 语句会释放定义游标时对数据加的锁,导致利用游标修改或删除数据的操作失败。
4.隐式游标
显式游标用于处理返回多行数据的 select 查询,但所有的SQL语句都有一个执行的缓冲区,隐式游标就是执行该缓冲区的指针,由系统隐含的打开、处理和关闭。隐式游标又称为SQL游标。
隐式游标主要用于处理 INSERT、UPDATE、DELETE 以及单行的 select ... into 语句,没有 OPEN、 FETCH、 CLOSE等操作命令。
与显式游标类似,隐式游标也有下列四个属性。
(1)SQL%ISOPEN
(2)SQL%FOUND
(3)SQL%NOTFOUND
(4)SQL%ROWCOUNT
BEGINUPDATE emp SET sal = sal+100 WHERE empno=1000; IF SQL%NOTFOUND THEN INSERT INTO emp(empno,sal) VALUES(1000,1500); END IF;END;
begin update emp set ENAME='ALEARK' WHERE EMPNO=7469; 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('游标指向了有效行');--判断游标是否指向有效行 else dbms_output.put_line('Sorry'); end if; if sql%notfound then dbms_output.put_line('Also Sorry'); else dbms_output.put_line('Haha'); end if; dbms_output.put_line(sql%rowcount); exception when no_data_found then dbms_output.put_line('Sorry No data'); when too_many_rows then dbms_output.put_line('Too Many rows'); end;