当查询返回结果超过一行时,就需要一个显式游标,此时用户不能使用select into语句。PL/SQL管理隐式游标,当查询开始时隐式游标打开,查询结束时隐式游标自动关闭。显式游标在PL/SQL块的声明部分声明,在执行部分或异常处理部分打开,取出数据,关闭。
利用显式游标输出dept的部门号和部门名:
1 declare r_dept dept%rowtype;
2 cursor c_dept is select * from dept; --定义游标
3 begin
4 open c_dept; --打开游标
5 loop
6 fetch c_dept into r_dept; --使用游标
7 exit when c_dept%notfound;
8 dbms_output.put_line(r_dept.dname ||' ''s deptno is '||r_dept.deptno);
9 end loop;
10 close c_dept; --关闭游标
11* end;
SQL> set serveroutput on
SQL> /
ACCOUNTING 's deptno is 10
RESEARCH 's deptno is 20
SALES 's deptno is 30
OPERATIONS 's deptno is 40
使用隐式游标也能达到同样的效果:
1 declare
2 c_dept dept%rowtype;
3 begin
4 for c_dept in (select * from dept)
5 loop
6 dbms_output.put_line(c_dept.dname||'''s deptno is '||c_dept.deptno);
7 end loop;
8* end;
SQL> /
ACCOUNTING's deptno is 10
RESEARCH's deptno is 20
SALES's deptno is 30
OPERATIONS's deptno is 40
PL/SQL procedure successfully completed.
游标的属性 返回值类型 意义
1. %ROWCOUNT 整型 获得FETCH语句返回的数据行数
2. %FOUND 布尔型 最近的FETCH语句返回一行数据则为真,否则为假
3. %NOTFOUND 布尔型 与%FOUND属性返回值相反
4. %ISOPEN 布尔型 游标已经打开时值为真,否则为假
1 declare
2 r_ename varchar(14);
3 cursor c_ename is select ename from emp;
4 begin
5 open c_ename;
6 if c_ename%isopen then
7 loop
8 fetch c_ename into r_ename;
9 exit when c_ename%notfound;
10 dbms_output.put_line(r_ename);
11 end loop;
12 else
13 dbms_output.put_line('cursor c_ename is not open!');
14 end if;
15 close c_ename;
16* end;
SQL> /
SMITH
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS
JAMES
FORD
MILLER
PL/SQL procedure successfully completed.
在定义游标时可以指定传递变量:
游标传递变量:
declare
r_ename varchar(10);
r_empno number(4);
r_job varchar(9);
r_mgr varchar(10);
cursor c_emp(c_empno number) is
select a.empno,a.ename,a.job,b.ename
from emp a,emp b
where a.empno=c_empno and a.mgr=b.empno;
begin
open c_emp(&i_empno);
loop
fetch c_emp into r_empno,r_ename,r_job,r_mgr;
exit when c_emp%notfound;
dbms_output.put_line(r_ename||','||r_empno||','||r_job||','||r_mgr);
end loop;
end;
/
Enter value for i_empno: 7566
old 11: open c_emp(&i_empno);
new 11: open c_emp(7566);
JONES,7566,MANAGER,KING
当然也可以直接通过变量进行传递
PL/SQL procedure successfully completed.
1 declare
2 r_ename varchar(10);
3 r_empno number(4);
4 r_job varchar(9);
5 r_mgr varchar(10);
6 cursor c_emp is
7 select a.empno,a.ename,a.job,b.ename
8 from emp a,emp b
9 where a.empno=&i_empno and a.mgr=b.empno;
10 begin
11 open c_emp;
12 loop
13 fetch c_emp into r_empno,r_ename,r_job,r_mgr;
14 exit when c_emp%notfound;
15 dbms_output.put_line(r_ename||','||r_empno||','||r_job||','||r_mgr);
16 end loop;
17* end;
SQL> /
Enter value for i_empno: 7566
old 9: where a.empno=&i_empno and a.mgr=b.empno;
new 9: where a.empno=7566 and a.mgr=b.empno;
JONES,7566,MANAGER,KING
PL/SQL procedure successfully completed.
使用动态select语句与游标结合:
动态select语句的用法:
1 declare
2 str varchar2(100);
3 e_name varchar(10);
4 begin
5 str:='select ename from emp where rownum < 2';
6 execute immediate str into e_name;
7 dbms_output.put_line(e_name);
8* end;
9 /
SMITH
PL/SQL procedure successfully completed.
将动态select语句与游标结合到一起:
1 declare
2 type emp_type is ref cursor;
3 str varchar2(100);
4 c_emp emp_type;
5 r_emp emp%rowtype;
6 begin
7 str:='select * from emp';
8 open c_emp for str;
9 loop
10 fetch c_emp into r_emp;
11 exit when c_emp%notfound;
12 dbms_output.put_line(r_emp.empno||','||r_emp.ename);
13 end loop;
14* end;
SQL> /
7369,SMITH
7499,ALLEN
7521,WARD
7566,JONES
7654,MARTIN
7698,BLAKE
7782,CLARK
7788,SCOTT
7839,KING
7844,TURNER
7876,ADAMS
7900,JAMES
7902,FORD
7934,MILLER
PL/SQL procedure successfully completed.
异常处理:
错误处理
错误处理部分位于程序的可执行部分之后,是由WHEN语句引导的多个分支构成的。错误处理的语法如下:
EXCEPTION
WHEN 错误1[OR 错误2] THEN
语句序列1;
WHEN 错误3[OR 错误4] THEN
语句序列2;
WHEN OTHERS
语句序列n;
END;
其中:
错误是在标准包中由系统预定义的标准错误,或是由用户在程序的说明部分自定义的错误,参见下一节系统预定义的错误类型。
语句序列就是不同分支的错误处理部分。
凡是出现在WHEN后面的错误都是可以捕捉到的错误,其他未被捕捉到的错误,将在WHEN OTHERS部分进行统一处理,OTHENS必须是EXCEPTION部分的最后一个错误处理分支。如要在该分支中进一步判断错误种类,可以通过使用预定义函数SQLCODE( )和SQLERRM( )来获得系统错误号和错误信息。
1. SET SERVEROUTPUT ON
2. DECLARE
3. v_temp NUMBER(5):=1;
4. BEGIN
5. v_temp:=v_temp/0;
6. EXCEPTION
7. WHEN OTHERS THEN
8. DBMS_OUTPUT.PUT_LINE('发生系统错误!');
9. DBMS_OUTPUT.PUT_LINE('错误代码:'|| SQLCODE( ));
10. DBMS_OUTPUT.PUT_LINE('错误信息:' ||SQLERRM( ));
11. END;
SET SERVEROUTPUT ON
DECLARE
v_temp NUMBER(5):=1;
BEGIN
v_temp:=v_temp/0;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('发生系统错误!');
DBMS_OUTPUT.PUT_LINE('错误代码:'|| SQLCODE( ));
DBMS_OUTPUT.PUT_LINE('错误信息:' ||SQLERRM( ));
END;
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29320885/viewspace-1148128/ ,如需转载,请注明出处,否则将追究法律责任。