enniscy 发表于 2013-2-4 20:23:34

oracle游标

一.概念:
游标:用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作。
二.分类:
1.静态游标:显式游标和隐式游标。
2.REF游标:是一种引用类型,类似于指针。
三.详细内容:
1.显式游标:
CURSOR游标名(参数) [返回值类型] ISSelect语句生命周期:
a.打开游标(OPEN)解析,绑定。。。不会从数据库检索数据
b.从游标中获取记录(FETCH INTO)执行查询,返回结果集。通常定义局域变量作为从游标获取数据的缓冲区。
c.关闭游标(CLOSE)完成游标处理,用户不能从游标中获取行。还可以重新打开。
选项:参数和返回类型
DECLARE
   CURSOR emp_cur (p_deptid IN NUMBER)
   IS
      SELECT *
      FROM employees
       WHERE department_id = p_deptid;

   l_emp   employees%ROWTYPE;
BEGIN
   DBMS_OUTPUT.put_line ('Getting employees from department 30');
   OPEN emp_cur (30);
   LOOP
      FETCH emp_cur
       INTO l_emp;
      EXIT WHEN emp_cur%NOTFOUND;
      DBMS_OUTPUT.put_line ('Employee id ' || l_emp.employee_id || ' is ');
      DBMS_OUTPUT.put_line (l_emp.first_name || ' ' || l_emp.last_name);
   END LOOP;
   CLOSE emp_cur;
   DBMS_OUTPUT.put_line ('Getting employees from department 90');
   OPEN emp_cur (90);
   LOOP
      FETCH emp_cur
       INTO l_emp;
      EXIT WHEN emp_cur%NOTFOUND;
      DBMS_OUTPUT.put_line ('Employee id ' || l_emp.employee_id || ' is ');
      DBMS_OUTPUT.put_line (l_emp.first_name || ' ' || l_emp.last_name);
   END LOOP;
   CLOSE emp_cur;
END;

2.隐式游标:不用明确建立游标变量,分两种:a.在PL/SQL中使用DML语言,使用ORACLE提供的名为SQL的隐示游标b.CURSOR FOR LOOP,用于for loop语句
a.举例:
DECLARE
BEGIN
   UPDATE c_order t
      SET t.description = 'haha'
    WHERE 1 = 2;
   IF SQL%NOTFOUND
   THEN
      DBMS_OUTPUT.put_line ('no records!');
   ELSE
      DBMS_OUTPUT.put_line ('update ' || SQL%ROWCOUNT || ' records');
   END IF;
END;
b.举例:
DECLARE
BEGIN
   FOR my_dept_rec IN (select documentno from c_order)
   LOOP
      DBMS_OUTPUT.put_line ('haha');
   END LOOP;
END;
c.举例:
单独select
DECLARE
   orderid   c_order.c_order_id%TYPE;
BEGIN
   SELECT c_order_id
   INTO orderid
   FROM c_order
    WHERE ROWNUM = 1;
   DBMS_OUTPUT.put_line (orderid);
END;
使用INTO获取值,只能返回一行。
游标属性:
%FOUND:变量最后从游标中获取记录的时候,在结果集中找到了记录。%NOTFOUND:变量最后从游标中获取记录的时候,在结果集中没有找到记录。%ROWCOUNT:当前时刻已经从游标中获取的记录数量。%ISOPEN:是否打开。

显式和隐式游标的区别:
尽量使用隐式游标,避免编写附加的游标控制代码(声明,打开,获取,关闭),也不需要声明变量来保存从游标中获取的数据。
3.REF CURSOR游标:
动态游标,在运行的时候才能确定游标使用的查询。分类:1.强类型(限制)REF CURSOR,规定返回类型2.弱类型(非限制)REF CURSOR,不规定返回类型,可以获取任何结果集。

强类型举例:
DECLARE
   --声明记录类型
   TYPE emp_job_rec IS RECORD (
      ID      NUMBER,
      docno   VARCHAR2 (50)
   );
   --声明REF CURSOR,返回值为该记录类型
   TYPE emp_job_refcur_type IS REF CURSOR
      RETURN emp_job_rec;
   --定义REF CURSOR游标的变量
   emp_refcur   emp_job_refcur_type;
   --定义记录类型变量
   emp_job      emp_job_rec;
BEGIN
   OPEN emp_refcur FOR
      SELECT   e.c_order_id, e.documentno
          FROM c_order e
         WHERE ROWNUM < 11
      ORDER BY 1;
   FETCH emp_refcur
    INTO emp_job;
   WHILE emp_refcur%FOUND
   LOOP
      DBMS_OUTPUT.put_line (   'ID = ' || emp_job.ID
                            || ' ' || 'DocNo = ' || emp_job.docno
                           );
      FETCH emp_refcur
       INTO emp_job;
   END LOOP;
END;
DECLARE
   --声明REF CURSOR,返回值rowtype
   TYPE emp_job_refcur_type IS REF CURSOR
      RETURN c_order%ROWTYPE;

   --定义REF CURSOR游标的变量
   emp_refcur   emp_job_refcur_type;
   --定义rowtype变量
   emp_job      c_order%ROWTYPE;
BEGIN
   OPEN emp_refcur FOR
      SELECT   e.*
          FROM c_order e
         WHERE ROWNUM < 11
      ORDER BY 1;

   FETCH emp_refcur
    INTO emp_job;

   WHILE emp_refcur%FOUND
   LOOP
      DBMS_OUTPUT.put_line (emp_job.documentno);

      FETCH emp_refcur
       INTO emp_job;
   END LOOP;
END;
页: [1]
查看完整版本: oracle游标