cursor分为三种,一是直接声明为cursor变量,二是首先声明类型再声明变量,三是声明为sys_refcursor。

(1)直接声明

declare

cursor emp_cur  is select *  from emp;

emp_record emp%rowtype;

begin

open emp_cur;

loop

fetch emp_cur  into emp_record;

exit when  emp_cur%notfound;

dbms_output.put_line('name is:' || emp_record.ename ||' and sal is:' || emp_record.sal);

end loop;

close emp_cur;

end;

/

(2)ref cursor:分为强类型(有return子句的)和弱类型,强类型在使用时,其返回类型必须和return中的类型一致,否则报错,而弱类型可以随意打开任何类型。

例如:

强类型

declare

type emp_cur_type  is ref cursor return emp%rowtype;

emp_cur emp_cur_type;

emp_record emp%rowtype;

begin

open emp_cur  for select *  from  emp;

loop

fetch emp_cur  into emp_record;

exit when emp_cur%notfound;

dbms_output.put_line('name is:' ||  emp_record.ename || ' and sal is:' || emp_record.sal);

end loop;

close emp_cur;

--open emp_cur for select * from dept; 错误的,类型不一致。

--close emp_cur;

end;

/

弱类型:

declare

type emp_cur_type is ref cursor;

emp_cur emp_cur_type;

emp_record emp%rowtype;

dept_record dept%rowtype;

begin

open emp_cur for select *  from emp;

loop

fetch emp_cur into emp_record;

exit when emp_cur%notfound;

dbms_output.put_line('name is:' || emp_record.ename || ' and sal is:' || emp_record.sal);

end loop;

close emp_cur;

open emp_cur  for select *  from dept; --可再次打开,不同类型的

loop

fetch emp_cur  into dept_record;

exit when emp_cur%notfound;

dbms_output.put_line('dname is:' || dept_record.dname);

end loop;

close emp_cur;

end;

/

(3)sys_refcursor:可多次打开,直接声明此类型的变量,不用先定义类型再声明变量。

declare

emp_cur sys_refcursor;

emp_record emp%rowtype;

dept_record dept%rowtype;

begin

open emp_cur for select *  from emp;

loop

fetch emp_cur  into emp_record;

exit when emp_cur%notfound;

dbms_output.put_line('name is:' || emp_record.ename || ' and sal is:' || emp_record.sal);

end loop;

close emp_cur;

open emp_cur  for select *  from dept; --可再次打开,不同类型的

loop

fetch emp_cur  into dept_record;

exit when emp_cur%notfound;

dbms_output.put_line('dname is:' || dept_record.dname);

end loop;

close emp_cur;

end;

/

其他总结:

1、游标可以用for循环,但只限于cursor cur_var is ……这种类型,用在其他的里面都是错误的;for本身就包含了打开、关闭游标,此时再显示打开关闭都是错误的。

declare

cursor emp_cur is select *  from emp;

begin

--open emp_cur; 是错误的,因为for本身就包含了打开、关闭

for emp_record in emp_cur

loop

dbms_output.put_line('name is:' ||  emp_record.ename || ' and sal is:' || emp_record.sal);

end loop;

--close emp_cur; 是错误的,for本身包含了关闭。

end;

--是不是表示:ref cursor变量不支持for打开并循环?

declare

type emp_cur_type  is ref cursor return emp%rowtype;

emp_cur emp_cur_type;

begin

open emp_cur  for select *  from emp;--怎么都是错,for已经打开了。

for emp_record  in emp_cur -- 不管前面有没有打开语句,for都不承认这种类型

loop

dbms_output.put_line('name is:' ||  emp_record.ename || ' and sal is:' || emp_record.sal);

end loop;

end;

2、游标可以带参数

DECLARE

CURSOR c1 (job VARCHAR2, max_wage NUMBER) IS

SELECT * FROM employees  WHERE job_id = job  AND salary > max_wage;

BEGIN

FOR person  IN  c1('CLERK', 3000)

LOOP

DBMS_OUTPUT.PUT_LINE('Name = ' || person.last_name || ', salary = ' ||

person.salary || ', Job Id = ' || person.job_id );

END LOOP;

END;

3、bulk collect批量赋值

declare

type emp_cur_type  is ref cursor;

emp_cur emp_cur_type;

type name_list is table of emp.ename%type;

type sal_list  is table of emp.sal%type;

names name_list;

sals sal_list;

begin

open emp_cur for select ename,sal from emp;

fetch emp_cur bulk collect into names,sals;

close emp_cur;

for i  in names.first .. names.last

loop

dbms_output.put_line('name is:'||names(i)||' and sal is:'||sals(i));

end loop;

end;

/

4、cursor变量的位置

CREATE PACKAGE emp_data AS

TYPE EmpCurTyp IS REF CURSOR RETURN employees%ROWTYPE;

-- emp_cv EmpCurTyp; -- not allowed

PROCEDURE open_emp_cv;

END  emp_data;

/

CREATE PACKAGE BODY emp_data  AS

-- emp_cv EmpCurTyp; -- not allowed

PROCEDURE open_emp_cv  IS

emp_cv EmpCurTyp; -- this is legal

BEGIN

OPEN emp_cv  FOR SELECT *  FROM  employees;

END  open_emp_cv;

END  emp_data;

/

5、嵌套cursor

打开父cursor时,子cursor隐含打开;当

语法格式:cursor(subquery)

A   nested  cursor  is  implicitly  opened when  the  containing  row  is  fetched from  the  parent  cursor.

The  nested  cursor  is  closed  only  when:

The  nested  cursor  is  explicitly  closed by  the  user

The  parent  cursor  is  reexecuted

The  parent  cursor  is  closed

The  parent  cursor  is  canceled

示例;
declare

type emp_cur_type  is ref cursor ;

type dept_cur_type is ref cursor ;

v_ename emp.ename%type;

v_dname dept.dname%type;

emp_cur emp_cur_type;

dept_cur dept_cur_type;

begin

open dept_cur  for

select d.dname,

cursor(select  e.ename  from  emp  e  where e.deptno=d.deptno )emps

from dept d;

loop

fetch dept_cur into v_dname,emp_cur;

exit when dept_cur%notfound;

dbms_output.put_line('dname is : '||v_dname);

loop

fetch emp_cur into  v_ename;

exit when emp_cur%notfound;

dbms_output.put_line('--ename is : '||v_ename);

end  loop;

end  loop;

close  dept_cur;

end;

Oracle Cursor用法总结的更多相关文章

  1. ORACLE RETURNING 用法总结

    ORACLE RETURNING 用法总结 场景 在存储过程.PL/SQL块里需要返回INSERT.DELETE.UPDATE.MERGE等DML语句执行后的信息时使用,合理使用returning能够 ...

  2. Oracle触发器用法实例详解

    转自:https://www.jb51.net/article/80804.htm. 本文实例讲述了Oracle触发器用法.分享给大家供大家参考,具体如下: 一.触发器简介 触发器的定义就是说某个条件 ...

  3. [转载]Oracle触发器用法实例详解

    本文实例讲述了Oracle触发器用法.分享给大家供大家参考,具体如下: 一.触发器简介 触发器的定义就是说某个条件成立的时候,触发器里面所定义的语句就会被自动的执行. 因此触发器不需要人为的去调用,也 ...

  4. Oracle instr用法

    1:实现indexOf功能,.从第1个字符开始,搜索第1次出现子串的位置 ,) as i from dual; select instr('oracle','or') as i from dual; ...

  5. Oracle minus用法详解及应用实例

    本文转载:https://blog.csdn.net/jhon_03/article/details/78321937 Oracle minus用法 “minus”直接翻译为中文是“减”的意思,在Or ...

  6. ORACLE SEQUENCE用法(转)

    ORACLE SEQUENCE用法 在oracle中sequence就是序号,每次取的时候它会自动增加.sequence与表没有关系. 1.Create Sequence     首先要有CREATE ...

  7. Oracle cursor学习笔记

    目录 一.oracle库缓存 1.1.库缓存简介 1.2.相关概念 1.3.库缓存结构 1.4.sql执行过程简介 二.oracle cursor 2.1.cursor分类 2.2.shared cu ...

  8. Oracle数据库用法汇总

    一些Oracle数据库用法的小总结 1.使用insert into创建新表 insert into destdb.sub_contract (userid,contractid) select msi ...

  9. oracle中REF Cursor用法

    from:http://www.111cn.net/database/Oracle/42873.htm 1,什么是 REF游标 ? 动态关联结果集的临时对象.即在运行的时候动态决定执行查询. 2,RE ...

随机推荐

  1. Qt button和buttons区别

    假设我的鼠标左键已经按下.若移动鼠标,会发生的move事件,button返回Qt::NoButton,buttons返回LeftButton.再按下右键,会发生press事件,button返回Righ ...

  2. -第2章 JS方法实现下拉菜单显示和隐藏

    知识点 onmouseover 鼠标经过 onmouseout 鼠标移出 function 关键字 getElementsByTagName 获取一组标签 length 获取对象成员个数 思路 给一级 ...

  3. sed命令使用详解

        内容来自马哥视频,感谢马哥精彩讲解 sed:编辑器 sed: Stream EDitor, 行编辑器,逐行进行处理 grep:实现文本过滤 awk:文本报告生成器 sed默认不编辑源文件,而是 ...

  4. codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    题目链接:Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 第一次写\(dsu\ on\ tree\),来记录一下 \(dsu\ o ...

  5. Git 基础 - 打标签

    列出现有标签(或者使用git tag -l) $ git tag v0. v1. 如果只对 1.4.2 系列的版本感兴趣 $ git tag -l 'v1.4.2.*' v1. v1. v1. v1. ...

  6. Array、List和ArrayList的区别(推荐: 浅显易懂)

    数组.List和ArrayList的区别(推荐: 浅显易懂)   有些知识点可能平时一直在使用,不过实际开发中我们可能只是知其然不知其所以然,所以经常的总结会对我们的提高和进步有很大的帮助,这里记录自 ...

  7. 远程Service的显示 / 隐式启动

    在进程间通信时,常会设计开启远程 Service 的情况.开启远程 Service 的方式有两种,一种时显示开启,一种是隐式开启.下面分别来看: 一.隐式开启 服务端:Service 所在 Andro ...

  8. PCA分析和因子分析

    #由此说明使用prcomp函数时,必须使用标准化过的原始数据.如果使用没有标准化的raw数据(不是相关系数矩阵或者协方差矩阵),必须将参数scale. = T <result>$sdev ...

  9. 《剑指offer》第四十五题(把数组排成最小的数)

    // 面试题45:把数组排成最小的数 // 题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼 // 接出的所有数字中最小的一个.例如输入数组{3, 32, 321},则打印出这3 ...

  10. DAY3 数据类型与运算符

    一.注释 代码注释分单行和多行注释, 单行注释用#,多行注释可以用三对双引号""" """ 注释用于解释某一行代码的作用,增加代码的可读性 ...