oracle 游标变量ref cursor详解
一 介绍
像游标cursor一样,游标变量ref cursor指向指定查询结果集当前行。游标变量显得更加灵活因为其声明并不绑定指定查询。
其主要运用于PLSQL函数或存储过程以及其他编程语言java等程序之间作为参数传递。
不像游标的一点,游标变量没有参数。
游标变量具有以下属性:
(%FOUND, %NOTFOUND, %ISOPEN, and %ROWCOUNT)
二 用法介绍:
1、声明格式:
DECLARE
TYPE DeptCurTyp IS REF CURSOR RETURN departments%ROWTYPE;
2、游标变量又分为强类型strong(with a return type)和弱类型(with no return type):
DECLARE
TYPE empcurtyp IS REF CURSOR RETURN employees%ROWTYPE; -- 强类型
TYPE genericcurtyp IS REF CURSOR; -- 弱类型
cursor1 empcurtyp;
cursor2 genericcurtyp;
my_cursor SYS_REFCURSOR; -- 使用预定义游标变量sys_refcursor
TYPE deptcurtyp IS REF CURSOR RETURN departments%ROWTYPE;
dept_cv deptcurtyp; -- 声明游标变量
或是返回record类型:
DECLARE
TYPE EmpRecTyp IS RECORD (
employee_id NUMBER,
last_name VARCHAR2(25),
salary NUMBER(8,2));
TYPE EmpCurTyp IS REF CURSOR RETURN EmpRecTyp;
emp_cv EmpCurTyp; -- declare cursor variable
3、使用游标变量作为参数传递:
DECLARE
TYPE empcurtyp IS REF CURSOR RETURN employees%ROWTYPE;
emp empcurtyp;
-- after result set is built, process all the rows inside a single procedure
-- rather than calling a procedure for each row
PROCEDURE process_emp_cv (emp_cv IN empcurtyp) IS
person employees%ROWTYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE('-----');
DBMS_OUTPUT.PUT_LINE('Here are the names from the result set:');
LOOP
FETCH emp_cv INTO person;
EXIT WHEN emp_cv%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Name = ' || person.first_name ||
' ' || person.last_name);
END LOOP;
END;
BEGIN
-- First find 10 arbitrary employees.
OPEN emp FOR SELECT * FROM employees WHERE ROWNUM < 11;
process_emp_cv(emp);
CLOSE emp;
-- find employees matching a condition.
OPEN emp FOR SELECT * FROM employees WHERE last_name LIKE 'R%';
process_emp_cv(emp);
CLOSE emp;
END;
/
4、使用游标熟悉检查游标变量是否打开
DECLARE
TYPE empcurtyp IS REF CURSOR RETURN employees%ROWTYPE;
emp_cv empcurtyp;
BEGIN
IF NOT emp_cv%ISOPEN THEN -- open cursor variable
OPEN emp_cv FOR SELECT * FROM employees;
END IF;
CLOSE emp_cv;
END;
/
5、在包package中声明游标变量:
CREATE PACKAGE emp_data AS
TYPE empcurtyp IS REF CURSOR RETURN employees%ROWTYPE;
PROCEDURE open_emp_cv (emp_cv IN OUT empcurtyp);
END emp_data;
/
CREATE PACKAGE BODY emp_data AS
PROCEDURE open_emp_cv (emp_cv IN OUT EmpCurTyp) IS
BEGIN
OPEN emp_cv FOR SELECT * FROM employees;
END open_emp_cv;
END emp_data;
/
6、提取游标变量到集合类型collection:
DECLARE
TYPE empcurtyp IS REF CURSOR;
TYPE namelist IS TABLE OF employees.last_name%TYPE;
TYPE sallist IS TABLE OF employees.salary%TYPE;
emp_cv empcurtyp;
names namelist;
sals sallist;
BEGIN
OPEN emp_cv FOR SELECT last_name, salary FROM employees
WHERE job_id = 'SA_REP';
FETCH emp_cv BULK COLLECT INTO names, sals;
CLOSE emp_cv;
-- loop through the names and sals collections
FOR i IN names.FIRST .. names.LAST
LOOP
DBMS_OUTPUT.PUT_LINE('Name = ' || names(i) || ', salary = ' || sals(i));
END LOOP;
END;
/
三 游标变量的使用限制:
1、不能再包说明中声明游标变量;
2、不能用“=”运算符比较游标变量相等性、不等性及是否为空;
3、不能存储于表列中;
4、不能将游标变量存在于关联数组、嵌套表或数组;
5、游标和游标变量之前是不可互操作的!
--------------------------------------------------------------------------------------
附:
------------------------
1、强类型游标:
CREATE OR REPLACE PACKAGE strongly_typed IS
TYPE return_cur IS REF CURSOR RETURN all_tables%ROWTYPE;
PROCEDURE child(p_return_rec OUT return_cur);
PROCEDURE parent(p_NumRecs PLS_INTEGER);
END strongly_typed;
/
CREATE OR REPLACE PACKAGE BODY strongly_typed IS
PROCEDURE child(p_return_rec OUT return_cur) IS
BEGIN
OPEN p_return_rec FOR
SELECT * FROM all_tables;
END child;
--==================================================
PROCEDURE parent (p_NumRecs PLS_INTEGER) IS
p_retcur return_cur;
at_rec all_tables%ROWTYPE;
BEGIN
child(p_retcur);
FOR i IN 1 .. p_NumRecs
LOOP
FETCH p_retcur
INTO at_rec;
dbms_output.put_line(at_rec.table_name ||
' - ' || at_rec.tablespace_name ||
' - ' || TO_CHAR(at_rec.initial_extent) ||
' - ' || TO_CHAR(at_rec.next_extent));
END LOOP;
END parent;
END strongly_typed;
/
set serveroutput on
exec strongly_typed.parent(1);
exec strongly_typed.parent(8);
2、弱类型游标:
CREATE OR REPLACE PROCEDURE child (
p_NumRecs IN PLS_INTEGER,
p_return_cur OUT SYS_REFCURSOR)
IS
BEGIN
OPEN p_return_cur FOR
'SELECT * FROM all_tables WHERE rownum <= ' || p_NumRecs ;
END child;
/
CREATE OR REPLACE PROCEDURE parent (pNumRecs VARCHAR2) IS
p_retcur SYS_REFCURSOR;
at_rec all_tables%ROWTYPE;
BEGIN
child(pNumRecs, p_retcur);
FOR i IN 1 .. pNumRecs
LOOP
FETCH p_retcur
INTO at_rec;
dbms_output.put_line(at_rec.table_name ||
' - ' || at_rec.tablespace_name ||
' - ' || TO_CHAR(at_rec.initial_extent) ||
' - ' || TO_CHAR(at_rec.next_extent));
END LOOP;
END parent;
/
set serveroutput on
exec parent(1);
exec parent(17);
3、预定义游标变量:
CREATE TABLE employees (
empid NUMBER(5),
empname VARCHAR2(30));
INSERT INTO employees (empid, empname) VALUES (1, 'Dan Morgan');
INSERT INTO employees (empid, empname) VALUES (2, 'Hans Forbrich');
INSERT INTO employees (empid, empname) VALUES (3, 'Caleb Small');
COMMIT;
CREATE OR REPLACE PROCEDURE pass_ref_cur(p_cursor SYS_REFCURSOR) IS
TYPE array_t IS TABLE OF VARCHAR2(4000)
INDEX BY BINARY_INTEGER;
rec_array array_t;
BEGIN
FETCH p_cursor BULK COLLECT INTO rec_array;
FOR i IN rec_array.FIRST .. rec_array.LAST
LOOP
dbms_output.put_line(rec_array(i));
END LOOP;
END pass_ref_cur;
/
set serveroutput on
DECLARE
rec_array SYS_REFCURSOR;
BEGIN
OPEN rec_array FOR
'SELECT empname FROM employees';
pass_ref_cur(rec_array);
CLOSE rec_array;
END;
/
-----------------------------------------------------
Dylan presents.
oracle 游标变量ref cursor详解的更多相关文章
- Oracle中的substr()函数 详解及应用
注:本文来源于<Oracle中的substr()函数 详解及应用> 1)substr函数格式 (俗称:字符截取函数) 格式1: substr(string string, int a, ...
- oracle数据库的完整性约束规则详解
CSDN日报20170303--<百亿互金平台救火故事> 程序员2月书讯 社区有奖问答--一起舞动酷炫的iOS动画 基于Spark的分布式深度学习和认知计算 oracle数据库的完 ...
- oracle中的dual表详解
oracle中的dual表详解 1.DUAL表的用途 Dual 是 Oracle中的一个实际存在的表,任何用户均可读取,常用在没有目标表的Select语句块中 --查看当前连接用户 SQL> s ...
- oracle数据库exp/imp命令详解
转自http://wenku.baidu.com/link?url=uD_egkkh7JtUYJaRV8YM6K8CLBT6gPJS4UlSy5WKhz46D9bnychTPdgJGd7y6UxYtB ...
- oracle正则表达式regexp_like的用法详解
oracle正则表达式regexp_like的用法详解 /*ORACLE中的支持正则表达式的函数主要有下面四个:1,REGEXP_LIKE :与LIKE的功能相似2,REGEXP_INSTR :与IN ...
- Oracle 查询优化的基本准则详解
注:报文来源:想跌破记忆寻找你 < Oracle 查询优化的基本准则详解 > Oracle 查询优化的基本准则详解 1:在进行多表关联时,多用 Where 语句把单个表的结果集最小化, ...
- 【转载】MyBatis JdbcType 与Oracle、MySql数据类型对应关系详解
[原文链接]:MyBatis JdbcType 与Oracle.MySql数据类型对应关系详解 1. Mybatis JdbcType与Oracle.MySql数据类型对应列表 2. Mybatis ...
- Node.js中环境变量process.env详解
Node.js中环境变量process.env详解process | Node.js API 文档http://nodejs.cn/api/process.html官方解释:process 对象是一个 ...
- 深入MySQL用户自定义变量:使用详解及其使用场景案例
一.前言 在前段工作中,曾几次收到超级话题积分漏记的用户反馈.通过源码的阅读分析后,发现问题出在高并发分布式场景下的计数器上.计数器的值会影响用户当前行为所获得积分的大小.比如,当用户在某超级话题下连 ...
- Oracle排名函数(Rank)实例详解
这篇文章主要介绍了Oracle排名函数(Rank)实例详解,需要的朋友可以参考下 --已知:两种排名方式(分区和不分区):使用和不使用partition --两种计算方式(连续,不连续),对应 ...
随机推荐
- [转帖]prometheus和node_exporter中的磁盘监控
https://www.ipcpu.com/2021/04/prometheus-node_exporter/ prometheus和node_exporter中的磁盘监控.md 对于磁盘问题,我们主 ...
- [转帖]Linux文件系统的几个性能测试软件小结
https://developer.aliyun.com/article/297631#:~:text=Linux%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E7%9A% ...
- [转帖]py_innodb_page_info.py工具使用
目录 一.Linux安装Python3 1. 解压包 2. 安装环境 3. 生成编译脚本 4. 检查python3.10的编译器 5. 建立Python3和pip3的软链 6. 添加到PATH 7. ...
- [转帖]SpringBoot项目banner.txt生成教程
文章目录 近期在做毕业设计,后端框架用到了SpringBoot,可以自己个性化设置banner.txt 地址:https://www.bootschool.net/ascii 可以直接下载,然后直接将 ...
- K8S 使用loki 监控 应用日志的搭建办法
1. 背景 这几天一直在用k8s部署分SU的测试环境,开发反馈看日志比较麻烦. 昨天晚上在家里本来想搭建ELK 发现比较重, 又说有一个比较轻量级的 loki 可以实现使用grafana进行监控和查看 ...
- node中的优先从缓存中加载模块与模块的加载规则
执行 node main.js 请问 b模块会被加载几次 //main.js require('./a.js') var fn = require('./b.js') console.log(fn.s ...
- diff算法是如何比较的,保证让你看的明明白白的!
更新dom节点,最小力度去跟新 index.html <body> <h1>你好啊!</h1> <button id="btn">该 ...
- js下拉加载更多-详解
场景 有些时候,我们在pc端经常会遇见滚动到底部的时候,去加载下一页的数据, 这个时候,我们就需要知道滚动条什么时候触底了, 如果触底了,就去加载下一页的数据; 在触底的过程中,我们需要注意的是,防止 ...
- 每日一库:Memcache
Memcache 是一个高性能.分布式的内存缓存系统,常用于缓存数据库查询结果.API调用结果.页面内容等,以提升应用程序的性能和响应速度.下面详细介绍一些 Memcache 的特点和使用方式: 内存 ...
- Git的使用(二):远程仓库
在github上创建远程仓库 本地创建Git仓库适合自己一个人完成工程,但是实际情况中我们需要其他人来协作开发,此时就可以把本地仓库同步到远程仓库,同时还增加了本地仓库的一个备份.常用的远程仓库就是g ...