declare
v_count NUMBER;
begin
select count(*) into v_count from emp;
dbms_output.put_line('sql%rowcount =' || sql%rowcount);
end;
/
declare
begin
INSERT into DEPT(DEPTNO,DNAME,LOC) VALUES(80,'firefox','shanghai');
dbms_output.put_line('sql%rowcount =' || sql%rowcount);
end;
/
declare
begin
update DEPT SET DNAME = 'firefox.COMMIT';
dbms_output.put_line('sql%rowcount' || sql%rowcount);
end;
/
--通过以上几个简单的程序可以发现隐式游标一直存在,但是隐式游标有很多种;
declare
v_empRow emp%ROWTYPE ; --保存emp一行数据;
begin
select * into v_empRow from emp where EMPNO = 7369;
if SQL%FOUND THEN
dbms_output.put_line('name is :' || v_empRow.ENAME || ',JOB is :' ||
v_empRow.JOB);
end if;
end;
/
--单行隐士游标
declare
begin
update emp SET SAL=SAL*1.2 where 1=2;
if sql%FOUND THEN
dbms_output.put_line('update rowcount:' || sql%rowcount);
else
dbms_output.put_line('NOT FOUND data update');
end if;
end;
/
--多行隐士游标;
--范例:定义显示游标;
declare
cursor cur_emp is select * from emp;
v_empRow emp%ROWTYPE;
begin
--游标如果要操作一定要保证其已经打开
if cur_emp%isopen THEN
NULL; --什么都不做
else
open cur_emp; --打开游标
end if;
--默认情况下游标在第一行记录上
fetch cur_emp into v_empRow; --取得当前行数据
while cur_emp%FOUND loop
dbms_output.put_line('rowmeber is :' || cur_emp%rowcount ||',name is : ' || v_empRow.ename ||
', JOB is :'|| v_empRow.JOB || ',sal is : ' || v_empRow.sal );
fetch cur_emp into v_empRow; --把游标指向下一行;
end loop;
close cur_emp;
end;
/
--使用loop循环
declare
cursor cur_emp is select * from emp;
v_empRow emp%ROWTYPE;
begin
--游标如果要操作一定要保证其已经打开
if cur_emp%isopen THEN
NULL; --什么都不做
else
open cur_emp; --打开游标
end if;
--默认情况下游标在第一行记录上
loop
fetch cur_emp into v_empRow;
exit when cur_emp%NOTFOUND; --没有数据推出循环
dbms_output.put_line('rowmeber is :' || cur_emp%rowcount ||',name is : ' || v_empRow.ename ||
', JOB is :'|| v_empRow.JOB || ',sal is : ' || v_empRow.sal );
end loop;
close cur_emp;
end;
/
--使用for循环进行游标操作:
declare
cursor cur_emp return emp%ROWTYPE is select * from emp;
v_empRow emp%ROWTYPE;
begin
for v_empRow in cur_emp loop
exit when cur_emp%NOTFOUND; --没有数据推出循环
dbms_output.put_line('rowmeber is :' || cur_emp%rowcount ||',name is : ' || v_empRow.ename ||
', JOB is :'|| v_empRow.JOB || ',sal is : ' || v_empRow.sal );
end loop;
end;
/
--偷懒for循环进行游标操作;
declare
begin
for v_empRow in (select * from emp)loop
dbms_output.put_line(',name is : ' || v_empRow.ename ||
', JOB is :'|| v_empRow.JOB || ',sal is : ' || v_empRow.sal );
end loop;
end;
/
--在动态select中使用游标;
declare
v_lowsal emp.sal%TYPE := &inputlowsal;
v_highsal emp.sal%TYPE := &inputhighsal;
cursor cur_emp is select * from emp where sal between v_lowsal and
v_highsal;
begin
for emp_row in cur_emp loop
dbms_output.put_line(cur_emp%rowcount || ',name is : ' ||
emp_row.ename || ', JOB is : ' || emp_row.JOB || ', sal : '
|| emp_row.sal);
end loop;
end;
/
--
declare
cursor cur_emp(p_dno emp.DEPTNO%TYPE) is select * from
emp where DEPTNO=p_dno;
begin
for emp_row in cur_emp(&inputDeptno) loop
dbms_output.put_line(cur_emp%rowcount || ', name is : ' ||
emp_row.ename || ', JOB is : ' || emp_row.JOB ||
'sal is :' || emp_row.sal);
end loop;
end;
/
范例:使用嵌套表接收游标数据
declare
TYPE dept_nested is table of dept%ROWTYPE;
v_dept dept_nested;
cursor cur_dept is select * from DEPT;
begin
if cur_dept%isopen THEN
null;
else
open cur_dept;
end if;
fetch cur_dept bulk collect into v_dept;
for x in v_dept.first .. v_dept.last loop
dbms_output.put_line('member is :' || v_dept(x).DEPTNO || ', name is : ' ||
v_dept(x).DNAME || ',localtion is : '|| v_dept(x).loc);
end loop;
close cur_dept;
end;
/
范例:将游标数据保存在可变数组之中;
declare
TYPE dept_varray is varray(4) of dept%ROWTYPE; --定义可变数组
v_dept dept_varray;
cursor cur_dept is select * from DEPT;
v_rows NUMBER := 4; --每次提取2行记录;
v_count NUMBER := 1; --每次少显示1行记录;
begin
if cur_dept%isopen THEN
null;
else
open cur_dept;
end if;
fetch cur_dept bulk collect into v_dept limit v_rows;
for x in v_dept.first .. (v_dept.last - v_count) loop
dbms_output.put_line('member is :' || v_dept(x).DEPTNO || ', name is : ' ||
v_dept(x).DNAME || ',localtion is : '|| v_dept(x).loc);
end loop;
close cur_dept;
end;
/
--游标更行操作
declare
cursor cur_emp is select * from emp;
begin
for emp_row in cur_emp loop
if emp_row.deptno = 10 then
if emp_row.sal*1.5 < 5000 then
update emp set sal = sal*1.5
where empno=emp_row.empno;
else
update emp set sal=5000
where empno=emp_row.empno;
end if;
elsif emp_row.deptno = 20 then
if emp_row.sal*1.22 < 5000 then
update emp set sal = sal*1.22
where empno=emp_row.empno;
else
update emp set sal=5000
where empno=emp_row.empno;
end if;
elsif emp_row.deptno = 30 then
if emp_row.sal*1.39 < 5000 then
update emp set sal = sal*1.39
where empno=emp_row.empno;
else
update emp set sal=5000
where empno=emp_row.empno;
end if;
else
null;
end if;
end loop;
exception
when others then
dbms_output.put_line('SQLCODE =' || SQLCODE);
dbms_output.put_line('SQLERRM =' || SQLERRM);
ROLLBACK;
end;
/
范例:创建一个不等待的游标;
declare
cursor cur_emp is select * from emp where deptno=10 for update nowait;
begin
for emp_row in cur_emp loop
update emp set sal=9999
where empno=emp_row.empno;
end loop;
end;
/
范例:使用where current of 子句:
declare
cursor cur_emp is select * from emp where deptno=10 for update;
begin
for emp_row in cur_emp loop
update emp set sal=9999
where current of cur_emp; --表示更新当前行的数据;
end loop;
end;
/
范例:使用游标删除表中数据:
declare
cursor cur_emp is select * from emp where deptno=10 for update
of sal,comm;
begin
for emp_row in cur_emp loop
delete from
emp
where current of cur_emp; --表示更新当前行的数据;
end loop;
end;
/
范例:创建一个多表查询的操作; --for update
declare
cursor cur_emp is
select e.ename,e.job,e.sal,d.dname,d.loc
FROM emp e , dept d
where e.deptno=d.deptno
and e.deptno=10 for update;
begin
for emp_row in cur_emp loop
update emp set sal=9999 where current of cur_emp;
end loop;
end;
/
declare
cursor cur_emp is
select e.ename,e.job,e.sal,d.dname,d.loc
FROM emp e , dept d
where e.deptno=d.deptno
and e.deptno=10 for update of sal;
begin
for emp_row in cur_emp loop
update emp set sal=9999 where current of cur_emp;
end loop;
end;
/
declare
type dept_ref is ref cursor return dept%ROWTYPE; --定义强类型游标
cur_dept dept_ref; --定义游标变量
v_deptRow dept%ROWTYPE; --定义行类型
begin
open cur_dept for select * from dept; --打开游标并决定游标类型
loop
fetch cur_dept into v_deptRow; --取得游标类型
exit when cur_dept%NOTFOUND; --如果没有数据就退出
dbms_output.put_line('name is : ' || v_deptRow.dname ||
',localtion : ' || v_deptRow.loc);
end loop;
close cur_dept;
end;
/
declare
type cursor_ref is ref cursor; --定义弱类型游标
cur_var cursor_ref; --定义游标变量
v_deptRow dept%ROWTYPE; --定义行类型
v_empRow emp%ROWTYPE; --定义行类型;
begin
open cur_var for select * from dept; --打开游标并决定游标类型
loop
fetch cur_var into v_deptRow; --取得游标类型
exit when cur_var%NOTFOUND; --如果没有数据就退出
dbms_output.put_line('1. name is : ' || v_deptRow.dname ||
',localtion : ' || v_deptRow.loc);
end loop;
close cur_var;
open cur_var for select * from emp where deptno = 10; -- 打开游标;
loop
fetch cur_var into v_empRow;
exit when cur_var%NOTFOUND;
dbms_output.put_line('2. name is :' || v_empRow.ename ||
'job is : ' || v_empRow.job);
end loop;
close cur_var;
exception
when ROWTYPE_MISMATCH then
dbms_output.put_line('游标数据类型不匹配异常. SQLCODE' || SQLCODE ||
'SQLERRM' || SQLERRM);
end;
/