ITPub博客

首页 > 数据库 > Oracle > CURSOR

CURSOR

原创 Oracle 作者:静以致远√团团 时间:2014-04-23 21:24:19 0 删除 编辑


当查询返回结果超过一行时,就需要一个显式游标,此时用户不能使用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博客 ” ,链接:http://blog.itpub.net/29320885/viewspace-1148128/,如需转载,请注明出处,否则将追究法律责任。

上一篇: SEQUENCE自增列
下一篇: oracle性能查看
请登录后发表评论 登录
全部评论
每个人都有梦想,去实现吧!

注册时间:2013-11-14

  • 博文量
    164
  • 访问量
    2103389