Oracle Cursor用法总结
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用法总结的更多相关文章
- ORACLE RETURNING 用法总结
ORACLE RETURNING 用法总结 场景 在存储过程.PL/SQL块里需要返回INSERT.DELETE.UPDATE.MERGE等DML语句执行后的信息时使用,合理使用returning能够 ...
- Oracle触发器用法实例详解
转自:https://www.jb51.net/article/80804.htm. 本文实例讲述了Oracle触发器用法.分享给大家供大家参考,具体如下: 一.触发器简介 触发器的定义就是说某个条件 ...
- [转载]Oracle触发器用法实例详解
本文实例讲述了Oracle触发器用法.分享给大家供大家参考,具体如下: 一.触发器简介 触发器的定义就是说某个条件成立的时候,触发器里面所定义的语句就会被自动的执行. 因此触发器不需要人为的去调用,也 ...
- Oracle instr用法
1:实现indexOf功能,.从第1个字符开始,搜索第1次出现子串的位置 ,) as i from dual; select instr('oracle','or') as i from dual; ...
- Oracle minus用法详解及应用实例
本文转载:https://blog.csdn.net/jhon_03/article/details/78321937 Oracle minus用法 “minus”直接翻译为中文是“减”的意思,在Or ...
- ORACLE SEQUENCE用法(转)
ORACLE SEQUENCE用法 在oracle中sequence就是序号,每次取的时候它会自动增加.sequence与表没有关系. 1.Create Sequence 首先要有CREATE ...
- Oracle cursor学习笔记
目录 一.oracle库缓存 1.1.库缓存简介 1.2.相关概念 1.3.库缓存结构 1.4.sql执行过程简介 二.oracle cursor 2.1.cursor分类 2.2.shared cu ...
- Oracle数据库用法汇总
一些Oracle数据库用法的小总结 1.使用insert into创建新表 insert into destdb.sub_contract (userid,contractid) select msi ...
- oracle中REF Cursor用法
from:http://www.111cn.net/database/Oracle/42873.htm 1,什么是 REF游标 ? 动态关联结果集的临时对象.即在运行的时候动态决定执行查询. 2,RE ...
随机推荐
- Derek解读Bytom源码-孤块管理
作者:Derek 简介 Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockchain/bytom ...
- docker 命令随笔
如果是容器传输文件到本地的话,反过来就好了: docker cp ID全称:容器文件路径 本地路径 2.进入docker 容器 docker exec -it fw-pay-trade-serv ...
- [luogu]P1852跳跳棋
题目重点是每次不能跳过两个棋子 即对于每一个棋子的状态(a,b,c) (a<b<c) 最多有两种移动的方式 1.中间往两边跳 (a,b,c)-->(2b-a,a,c)或(a,c,2b ...
- JS加载获取父窗体传递的参数
JS加载获取父窗体传递的参数 $(document).ready(function () { var query = location.search.substring(1); var values ...
- linux 校准时间方法
Debian.Ubuntu 系统安装NTP校时包: apt-get install ntpdate CentOS系统安装NTP校时包: yum install ntp 校时 ...
- bzoj 2243: [SDOI2011]染色 线段树区间合并+树链剖分
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 7925 Solved: 2975[Submit][Status ...
- win10 安装keras
1.安装Python环境 建议安装Anconda3 ,4.2.0版本 下载地址: https://repo.continuum.io/archive/index.html 或 https://mirr ...
- DLL.LoadLibrary失败(126)
1.LoadLibrary 返回 NULL,GetLastError 显示的是 错误码126,msdn上是这样的: ERROR_MOD_NOT_FOUND 126 (0x7E) The specifi ...
- [原][粒子特效][spark]深入浅出osgSpark
背景: 目前我使用的spark粒子特效库是2.0 这个库好像是原来鬼火引擎的一部分,需要从github上找 现在我要将其使用到我自己开发的基于osgearth开的三维地图引擎中 步骤: 1.编译spa ...
- hive表的存储路径查找以及表的大小
1.在hive中知道一个表的存储路径可以通过hive命令 desc formatted table_name 显示表的详细信息; 2.然后找到该表的存储路径 "Location: ...