oracle 游标变量ref cursor详解

oracle 游标变量ref cursor详解

分类: PL/SQL开发 2013-12-04 15:15 685人阅读 评论(0) 收藏 举报

oracleref 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、使用游标变量作为参数传递:

[sql] view plaincopy

  1. DECLARE
  2. TYPE empcurtyp IS REF CURSOR RETURN employees%ROWTYPE;
  3. emp empcurtyp;
  4. -- after result set is built, process all the rows inside a single procedure
  5. -- rather than calling a procedure for each row
  6. PROCEDURE process_emp_cv (emp_cv IN empcurtyp) IS
  7. person employees%ROWTYPE;
  8. BEGIN
  9. DBMS_OUTPUT.PUT_LINE(‘-----‘);
  10. DBMS_OUTPUT.PUT_LINE(‘Here are the names from the result set:‘);
  11. LOOP
  12. FETCH emp_cv INTO person;
  13. EXIT WHEN emp_cv%NOTFOUND;
  14. DBMS_OUTPUT.PUT_LINE(‘Name = ‘ || person.first_name ||
  15. ‘ ‘ || person.last_name);
  16. END LOOP;
  17. END;
  18. BEGIN
  19. -- First find 10 arbitrary employees.
  20. OPEN emp FOR SELECT * FROM employees WHERE ROWNUM < 11;
  21. process_emp_cv(emp);
  22. CLOSE emp;
  23. -- find employees matching a condition.
  24. OPEN emp FOR SELECT * FROM employees WHERE last_name LIKE ‘R%‘;
  25. process_emp_cv(emp);
  26. CLOSE emp;
  27. END;
  28. /

4、使用游标熟悉检查游标变量是否打开

[sql] view plaincopy

  1. DECLARE
  2. TYPE empcurtyp IS REF CURSOR RETURN employees%ROWTYPE;
  3. emp_cv empcurtyp;
  4. BEGIN
  5. IF NOT emp_cv%ISOPEN THEN -- open cursor variable
  6. OPEN emp_cv FOR SELECT * FROM employees;
  7. END IF;
  8. CLOSE emp_cv;
  9. END;
  10. /

5、在包package中声明游标变量:

[sql] view plaincopy

  1. CREATE PACKAGE emp_data AS
  2. TYPE empcurtyp IS REF CURSOR RETURN employees%ROWTYPE;
  3. PROCEDURE open_emp_cv (emp_cv IN OUT empcurtyp);
  4. END emp_data;
  5. /
  6. CREATE PACKAGE BODY emp_data AS
  7. PROCEDURE open_emp_cv (emp_cv IN OUT EmpCurTyp) IS
  8. BEGIN
  9. OPEN emp_cv FOR SELECT * FROM employees;
  10. END open_emp_cv;
  11. END emp_data;
  12. /

6、提取游标变量到集合类型collection:

[sql] view plaincopy

  1. DECLARE
  2. TYPE empcurtyp IS REF CURSOR;
  3. TYPE namelist IS TABLE OF employees.last_name%TYPE;
  4. TYPE sallist IS TABLE OF employees.salary%TYPE;
  5. emp_cv empcurtyp;
  6. names namelist;
  7. sals sallist;
  8. BEGIN
  9. OPEN emp_cv FOR SELECT last_name, salary FROM employees
  10. WHERE job_id = ‘SA_REP‘;
  11. FETCH emp_cv BULK COLLECT INTO names, sals;
  12. CLOSE emp_cv;
  13. -- loop through the names and sals collections
  14. FOR i IN names.FIRST .. names.LAST
  15. LOOP
  16. DBMS_OUTPUT.PUT_LINE(‘Name = ‘ || names(i) || ‘, salary = ‘ || sals(i));
  17. END LOOP;
  18. END;
  19. /

三 游标变量的使用限制:

1、不能再包说明中声明游标变量;

2、不能用“=”运算符比较游标变量相等性、不等性及是否为空;

3、不能存储于表列中;

4、不能将游标变量存在于关联数组、嵌套表或数组;

5、游标和游标变量之前是不可互操作的!

--------------------------------------------------------------------------------------

附:

------------------------

1、强类型游标:

[sql] view plaincopy

  1. CREATE OR REPLACE PACKAGE strongly_typed IS
  2. TYPE return_cur IS REF CURSOR RETURN all_tables%ROWTYPE;
  3. PROCEDURE child(p_return_rec OUT return_cur);
  4. PROCEDURE parent(p_NumRecs PLS_INTEGER);
  5. END strongly_typed;
  6. /

[sql] view plaincopy

  1. CREATE OR REPLACE PACKAGE BODY strongly_typed IS
  2. PROCEDURE child(p_return_rec OUT return_cur) IS
  3. BEGIN
  4. OPEN p_return_rec FOR
  5. SELECT * FROM all_tables;
  6. END child;
  7. --==================================================
  8. PROCEDURE parent (p_NumRecs PLS_INTEGER) IS
  9. p_retcur return_cur;
  10. at_rec   all_tables%ROWTYPE;
  11. BEGIN
  12. child(p_retcur);
  13. FOR i IN 1 .. p_NumRecs
  14. LOOP
  15. FETCH p_retcur
  16. INTO at_rec;
  17. dbms_output.put_line(at_rec.table_name ||
  18. ‘ - ‘ || at_rec.tablespace_name ||
  19. ‘ - ‘ || TO_CHAR(at_rec.initial_extent) ||
  20. ‘ - ‘ || TO_CHAR(at_rec.next_extent));
  21. END LOOP;
  22. END parent;
  23. END strongly_typed;
  24. /

[sql] view plaincopy

  1. set serveroutput on
  2. exec strongly_typed.parent(1);
  3. exec strongly_typed.parent(8);

2、弱类型游标:

[sql] view plaincopy

  1. CREATE OR REPLACE PROCEDURE child (
  2. p_NumRecs IN PLS_INTEGER,
  3. p_return_cur OUT SYS_REFCURSOR)
  4. IS
  5. BEGIN
  6. OPEN p_return_cur FOR
  7. ‘SELECT * FROM all_tables WHERE rownum <= ‘ || p_NumRecs ;
  8. END child;
  9. /
  10. CREATE OR REPLACE PROCEDURE parent (pNumRecs VARCHAR2) IS
  11. p_retcur  SYS_REFCURSOR;
  12. at_rec    all_tables%ROWTYPE;
  13. BEGIN
  14. child(pNumRecs, p_retcur);
  15. FOR i IN 1 .. pNumRecs
  16. LOOP
  17. FETCH p_retcur
  18. INTO at_rec;
  19. dbms_output.put_line(at_rec.table_name ||
  20. ‘ - ‘ || at_rec.tablespace_name ||
  21. ‘ - ‘ || TO_CHAR(at_rec.initial_extent) ||
  22. ‘ - ‘ || TO_CHAR(at_rec.next_extent));
  23. END LOOP;
  24. END parent;
  25. /
  26. set serveroutput on
  27. exec parent(1);
  28. exec parent(17);

3、预定义游标变量:

[sql] view plaincopy

  1. CREATE TABLE employees (
  2. empid   NUMBER(5),
  3. empname VARCHAR2(30));
  4. INSERT INTO employees (empid, empname) VALUES (1, ‘Dan Morgan‘);
  5. INSERT INTO employees (empid, empname) VALUES (2, ‘Hans Forbrich‘);
  6. INSERT INTO employees (empid, empname) VALUES (3, ‘Caleb Small‘);
  7. COMMIT;
  8. CREATE OR REPLACE PROCEDURE pass_ref_cur(p_cursor SYS_REFCURSOR) IS
  9. TYPE array_t IS TABLE OF VARCHAR2(4000)
  10. INDEX BY BINARY_INTEGER;
  11. rec_array array_t;
  12. BEGIN
  13. FETCH p_cursor BULK COLLECT INTO rec_array;
  14. FOR i IN rec_array.FIRST .. rec_array.LAST
  15. LOOP
  16. dbms_output.put_line(rec_array(i));
  17. END LOOP;
  18. END pass_ref_cur;
  19. /
  20. set serveroutput on
  21. DECLARE
  22. rec_array SYS_REFCURSOR;
  23. BEGIN
  24. OPEN rec_array FOR
  25. ‘SELECT empname FROM employees‘;
  26. pass_ref_cur(rec_array);
  27. CLOSE rec_array;
  28. END;
  29. /
时间: 2024-08-23 23:21:57

oracle 游标变量ref cursor详解的相关文章

Oracle ErrorStack 使用和阅读详解

一.概述 在Oracle数据库运行过程中,我们经常会遇到这样或那样的错误,但是错误的提示并不具体,加大了我们在诊断问题时的难度. ErrorStack是Oracle提供的一种对于错误堆栈进行跟踪的方法,通过设置跟踪可以将一些指定错误的后台信息详细的转储出来,写入跟踪文件,帮助我们诊断问题. 备注: 1.当oracle发生关键的错误诸如:ora-600,Errorstack是自动被oracle dump写入trace文件中. 2.当你在alert.log里面看见这类错误,并提示已经产生trace文

.Net的Oracle数据库ORM控件dotConnect for Oracle下载地址及功能详解

原文来自龙博方案网http://www.fanganwang.com/product/1330转载请注明出处 dotConnect for Oracle完全基于ADO.NET方法,因此您完全可以采用标准ADO.NET数据提供的方法来使用它.是一款为Microsoft .NET Framework提供直接Oracle数据库连接的数据发生器控件. 具体功能: 无需Oracle客户端,采用直接模式提供数据库连接 100%代码管理 具有高表现性能 支持Oracle 10g, 9i, 8i 和 8.0,包

Oracle中的substr()函数 详解及应用

注:本文来源于<Oracle中的substr()函数 详解及应用> 1)substr函数格式   (俗称:字符截取函数) 格式1: substr(string string, int a, int b); 格式2:substr(string string, int a) ; 解释: 格式1:        1.string 需要截取的字符串         2.a 截取字符串的开始位置(注:当a等于0或1时,都是从第一位开始截取)        3.b 要截取的字符串的长度 格式2:     

Oracle 12c Cluster Health Monitor 详解

注:本文谢绝转载! 1  CHM 概述 Cluster HealthMonitor 会通过OS API来收集操作系统的统计信息,如内存,swap 空间使用率,进程,IO 使用率,网络等相关的数据. CHM 的信息收集是实时的,在11.2.0.3 之前是每1秒收集一次,在11.2.0.3 之后,改成每5秒收集一次数据,并保存在CHM 仓库中. 这个收集时间间隔不能手工修改. CHM 的目的也是为了在出现问题时,提供一个分析的依据,比如节点重启,hang,实例被驱逐,性能下降,这些问题都可以通过对C

LINUX下ORACLE相关的内核参数详解

ORACLE相关的内核参数详解 1.kernel.sem [[email protected] ~]# cat /proc/sys/kernel/sem 250         32000    100         142 [[email protected] ~]#  ipcs -sl ------ Semaphore Limits -------- max number of arrays = 142 max semaphores per array = 250 max semaphor

oracle init.ora常用配置详解

参考网上整理了重要的配置文件 db_name = "51cto"   一个数据库标识符,应与CREATE DATABASE 语句中指定的名称相对应. instance_name = 51cto在多个例程使用相同服务名的情况下,用来唯一地标识一个数据库例程. INSTANCE_NAME 不应与 SID 混淆,它实际上是对在一台主机上共享内存的各个例程的唯一标识. service_names =  51cto为 Net8 监听程序可用于识别一个服务 (如:复制环境中的一个特定数据库) 的例

day01_linux中与Oracle有关的内核参数详解

linux中与Oracle有关的内核参数详解 在安装Oracle的时候需要调整linux的内核参数,但是各参数代表什么含义呢,下面做详细解析. Linux安装文档中给出的最小值: fs.aio-max-nr = 1048576 fs.file-max = 6815744 kernel.shmall = 2097152 kernel.shmmax = 4294967295 kernel.shmmni = 4096 kernel.sem = 250 32000 100 128 net.ipv4.ip

PHP100-第三讲 PHP5.4 语法、常量、变量、数据类型详解

内容摘要: ①PHP5.4 的基本语法与写作格式 ②PHP5.4 的变量与变量数据类型 ③PHP5.4 的系统常量与自定义常量 PHP5.4 的基本语法与写作格式: 任何程序语言都有自己的语言风格,PHP语言也有自己独特的风格,虽然也继承了许多Perl和C的语言特色.但经过多年的发展PHP已经成为了一个成熟 的编程语言,所以我们还需要认真的学习PHP的独特语法.PHP一个很大的特色就是与HTML标签语言进行混编,这种模式是今后很长一段学习过程中所用到 的格式,因此我们先来通过一个例子来认识一下P

深入MySQL用户自定义变量:使用详解及其使用场景案例

一.前言 在前段工作中,曾几次收到超级话题积分漏记的用户反馈.通过源码的阅读分析后,发现问题出在高并发分布式场景下的计数器上.计数器的值会影响用户当前行为所获得积分的大小.比如,当用户在某超级话题下连续第n(n即计数器的值)次进行转发帖子时,将会获得与n相关的分数.然而,在第一次改进后问题依然存在.所以,这次在之前的基础上,通过使用MySQL变量的途径来解决该问题. 二.到底MySQL的变量分哪几类? MySQL变量一共分为两大类:用户自定义变量和系统变量.如下: 用户自定义变量 局部变量 会话