Oracle数据库游标的类型及使用实例全解

游标是SQL的一个内存工作区,由系统或用户以变量的形式定义。游标的作用就是用于临时存储从数据库中提取的数据块。Oracle数据库的Cursor类型包含三种: 静态游标:分为显式(explicit)游标和隐式(implicit)游标;REF游标:是一种引用类型,类似于指针。下面我们一一介绍它们的使用。

1.隐式游标

1)Select …INTO…语句,DML语句,使用隐式Cursor。此外,还有一种使用FOR LOOP的Implicit Cursor用法。

2)可以通过隐式Cusor的属性来了解操作的状态和结果。Cursor的属性包含:

SQL%ROWCOUNT 整型代表DML语句成功执行的数据行数。

SQL%FOUND  布尔型值为TRUE代表插入、删除、更新或单行查询操作成功。

SQL%NOTFOUND 布尔型与SQL%FOUND属性返回值相反。

SQL%ISOPEN 布尔型DML执行过程中为真,结束后为假。

3) 隐式Cursor由系统自动打开和关闭.

例如:

  1. set serveroutput on    
  2.  
  3. declare    
  4.  
  5. begin      
  6.  
  7. update employees set employee_name='Mike' where employee_id=1001;    
  8.  
  9. if SQL%FOUND then      
  10.  
  11. dbms_output.put_line('Name is updated');    
  12.  
  13. else    
  14.  
  15. dbms_output.put_line('Name is not updated');    
  16.  
  17. end if;    
  18.  
  19. end;    
  20.  
  21. /    
  22.  
  23. set serveroutput on    
  24.  
  25. declare    
  26.  
  27. begin      
  28.  
  29. for tableInfo in (select * from user_tables) loop    
  30.  
  31. dbms_output.put_line(tableInfo.table_name);    
  32.  
  33. end loop;    
  34.  
  35. exception    
  36.  
  37. when others then    
  38.  
  39. dbms_output.put_line(sqlerrm);    
  40.  
  41. end;    
  42.  
  43. /  

2.显式游标

1) 显式Cursor的属性包含:

游标的属性   返回值类型   意义 

%ROWCOUNT   整型  获得FETCH语句返回的数据行数 

%FOUND  布尔型 最近的FETCH语句返回一行数据则为真,否则为假 

%NOTFOUND   布尔型 与%FOUND属性返回值相反 

%ISOPEN 布尔型 游标已经打开时值为真,否则为假  

2) 对于显式游标的运用分为四个步骤:

a 定义游标—Cursor  [Cursor Name]  IS;

b 打开游标—Open  [Cursor Name]; 

c  操作数据—Fetch  [Cursor name] 

d  关闭游标—Close [Cursor Name]

以下是几种常见显式Cursor用法。

  1. <p>set serveroutput on    
  2.  
  3. declare    
  4.  
  5. cursor cur is select * from user_tables;    
  6.  
  7. tableInfo user_tables%rowtype;    
  8.  
  9. begin    
  10.  
  11. open cur;        
  12.  
  13. loop    
  14.  
  15. fetch cur into tableInfo;    
  16.  
  17. exit when cur%notfound;    
  18.  
  19. dbms_output.put_line(tableInfo.table_name);    
  20.  
  21. end loop;</p><p>exception    
  22.  
  23. when others then    
  24.  
  25. dbms_output.put_line(sqlerrm);</p><p>  close cur;    
  26.  
  27. end;    
  28.  
  29. /</p>    
  30.  
  31. set serveroutput on    
  32.  
  33. declare    
  34.  
  35. cursor cur is select * from user_tables;    
  36.  
  37. begin      
  38.  
  39. for tableInfo in cur loop    
  40.  
  41. dbms_output.put_line(tableInfo.table_name);    
  42.  
  43. end loop;    
  44.  
  45. exception    
  46.  
  47. when others then    
  48.  
  49. dbms_output.put_line(sqlerrm);    
  50.  
  51. end;    
  52.  
  53. /  

还可以使用带参数open的cursor。

  1. <p>set serveroutput on    
  2.  
  3. declare    
  4.  
  5. cursor cur(tblName varchar2) is select * from user_constraints where table_name=tblName;    
  6.  
  7. tableInfo user_constraints%rowtype;    
  8.  
  9. begin    
  10.  
  11. open cur('EMPLOYEES');        
  12.  
  13. loop    
  14.  
  15. fetch cur into tableInfo;    
  16.  
  17. exit when cur%notfound;    
  18.  
  19. dbms_output.put_line(tableInfo.constraint_name);    
  20.  
  21. end loop;</p><p>exception    
  22.  
  23. when others then    
  24.  
  25. dbms_output.put_line(sqlerrm);</p><p>  close cur;    
  26.  
  27. end;    
  28.  
  29. /</p><p></p>    
  30.  
  31. set serveroutput on    
  32.  
  33. declare    
  34.  
  35. cursor cur(tblName varchar2) is select * from user_constraints where table_name=tblName;    
  36.  
  37. begin    
  38.  
  39. for tableInfo in cur('EMPLOYEES') loop    
  40.  
  41. dbms_output.put_line(tableInfo.constraint_name);    
  42.  
  43. end loop;    
  44.  
  45. exception    
  46.  
  47. when others then    
  48.  
  49. dbms_output.put_line(sqlerrm);    
  50.  
  51. end    
  52.  
  53. /  

可以使用WHERE CURRENT OF子句执行UPDATE或DELETE操作。

  1. set serveroutput on    
  2.  
  3. declare    
  4.  
  5. cursor cur is select * from employees for update;    
  6.  
  7. begin      
  8.  
  9. for tableInfo in cur loop    
  10.  
  11. update employees set salarysalary=salary*1.1 where current of cur;    
  12.  
  13. end loop;    
  14.  
  15. commit;    
  16.  
  17. exception    
  18.  
  19. when others then    
  20.  
  21. dbms_output.put_line(sqlerrm);    
  22.  
  23. end;    
  24.  
  25. /  

3.REF CURSOR(Cursor Variables)

REF Cursor在运行的时候才能确定游标使用的查询。利用REF CURSOR,可以在程序间传递结果集(一个程序里打开游标变量,在另外的程序里处理数据)。

也可以利用REF CURSOR实现BULK SQL,提高SQL性能。

REF CURSOR分两种,Strong REF CURSOR 和 Weak REF CURSOR。

Strong REF CURSOR:指定retrun type,CURSOR变量的类型必须和return type一致。

Weak REF CURSOR:不指定return type,能和任何类型的CURSOR变量匹配。

Ref cursor的使用:

1) Type [Cursor type name] is ref cursor 

2) Open cursor for…

3) Fetch  [Cursor name] 

4) Close Cursor

例如:

Step1:

  1. create or replace package TEST as    
  2.  
  3. type employees_refcursor_type is ref cursor return employees%rowtype;    
  4.  
  5. procedure employees_loop(employees_cur IN employees_refcursor_type);    
  6.  
  7. end TEST;    
  8.  
  9. /   

Step2:

  1. create or replace package body TEST as    
  2.  
  3. procedure employees_loop(employees_cur IN employees_refcursor_type) is    
  4.  
  5. emp employees%rowtype;    
  6.  
  7. begin    
  8.  
  9. loop    
  10.  
  11. fetch employees_cur into emp;    
  12.  
  13. exit when employees_cur%NOTFOUND;    
  14.  
  15. dbms_output.put_line(emp.employee_id);    
  16.  
  17. end loop;    
  18.  
  19. end employees_loop;    
  20.  
  21. end TEST;    
  22.  

Step3:

  1. set serveroutput on    
  2.  
  3. declare    
  4.  
  5. empRefCur TEST.employees_refcursor_type;    
  6.  
  7. begin    
  8.  
  9. for i in 10..20 loop    
  10.  
  11. dbms_output.put_line('Department ID=' || i);    
  12.  
  13. open empRefCur for select * from employees where department_id=i;    
  14.  
  15. TEST.employees_loop(empRefCur);    
  16.  
  17. end loop;    
  18.  
  19. exception    
  20.  
  21. when others then    
  22.  
  23. dbms_output.put_line(sqlerrm);    
  24.  
  25.  
  26. close empRefCur;    
  27.  
  28. end;    
  29.  

4.BULK SQL

使用FORALL和BULK COLLECT子句。利用BULK SQL可以减少PLSQL Engine和SQL Engine之间的通信开销,提高性能。

1. To speed up INSERT, UPDATE, and DELETE statements, enclose the SQL statement within a PL/SQL FORALL statement instead of a loop construct. 加速INSERT, UPDATE, DELETE语句的执行,也就是用FORALL语句来替代循环语句。

2. To speed up SELECT statements, include the BULK COLLECT INTO clause in the SELECT statement instead of using INTO.  加速SELECT,用BULK COLLECT INTO 来替代INTO。

  1. SQL> create table employees_tmp as select first_name, last_name, salary from employees where 0=1;  
  2.  
  3. set serveroutput on    
  4.  
  5. declare    
  6.  
  7. cursor employees_cur(depId employees.department_id%type) is select first_name, last_name, salary from employees where department_id=depId;    
  8.  
  9. type employee_table_type is table of employees_cur%rowtype index by pls_integer;    
  10.  
  11. employee_table employee_table_type;    
  12.  
  13. begin    
  14.  
  15. open employees_cur(100);    
  16.  
  17. fetch employees_cur bulk collect into employee_table;    
  18.  
  19. close employees_cur;    
  20.  
  21. for i in 1..employee_table.count loop    
  22.  
  23. dbms_output.put_line(employee_table(i).first_name || ' ' || employee_table(i).last_name || ',' || employee_table(i).salary);    
  24.  
  25. end loop;    
  26.  
  27. forall i in employee_table.first..employee_table.last    
  28.  
  29. insert into employees_tmp values(employee_table(i).first_name, employee_table(i).last_name, employee_table(i).salary);    
  30.  
  31. commit;    
  32.  
  33. end;    
  34.  
  35. /   

5.  动态性能表V$OPEN_CURSOR

本视图列出session打开的所有cursors。

关于Oracle数据库游标的类型和使用的知识就介绍到这里了,如果您想了解更多的Oracle数据库的知识,可以到这里看一下:http://database./oracle/,相信一定能够带给您收获的!

【编辑推荐】

  1. MySQL数据库如何实现跨表更新与数据并合
  2. 关于Oracle利用UTL_INADDR注入的简单介绍
  3. MySQL数据库修改MySQL密码的六种措施总结
  4. Oracle数据库定时器Job在各个时间的写法总结篇
  5. 关于MySQL数据库索引和ORDER BY子句的使用问题简介

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/244260.html<

(0)
管理的头像管理
上一篇2025-04-25 15:47
下一篇 2025-04-25 15:48

相关推荐

  • jsp空间购买和交换数据空间怎么买,有哪些注意事项?

    购买JSP空间时,是否考虑过数据交换空间的性能?简米科技(2003年始创,23年行业沉淀)与酷番云(工信部一类增值电信全牌照)这类持牌自营机房的服务商,能确保数据交换的高效稳定,是值得优先选择的合作伙伴,为什么JSP空间需要搭配独立的数据交换空间从JSP应用特性看数据交换需求JSP基于Java技术,常用于企业级……

    2026-08-11
    0
  • 建网站用香港空间效果怎么样,香港空间稳定吗?

    建网站用香港空间,对于创建网站资产来说,核心价值在于免备案和全球带宽优势,尤其适合外贸、跨境电商和需要快速启动的项目,但你必须权衡国内访问延迟,并选择有资质的服务商以保证资产安全,香港空间的核心优势与适用边界免备案:节省时间就是节省成本国内服务器需要备案,通常需要10到20天,香港空间无需备案,域名解析后即可上……

    2026-08-11
    0
  • Java连接云数据库的方法是什么,如何操作

    Java连接云数据库的核心在于通过JDBC驱动,结合云服务商提供的连接地址、端口、数据库名及认证信息,配置安全策略(如SSL、IP白名单),即可实现稳定高效的远程数据库访问,基础准备:JDBC驱动与依赖管理连接云数据库前,需要确保开发环境具备对应的JDBC驱动,以最常见的MySQL为例,你需要引入mysql-c……

    2026-08-11
    0
  • 建网站公安联网备案必须使用数据码吗,备案流程是什么

    网站备案包括ICP备案和公安联网备案,两者缺一不可,公安联网备案必须使用服务商提供的数据码,选择持有合法资质的服务商是顺利通过备案的前提,为什么网站必须进行公安联网备案根据公安部《计算机信息网络国际联网安全保护管理办法》,网站开通后30日内必须到公安机关办理备案手续,未完成公安备案的网站,面临责令整改、关闭网站……

    2026-08-10
    0
  • 建一个企业网站大概需要多少钱?,怎么收费?

    建网站要多少钱,没有一个固定的数字,几百到几万都可能,但真正的“创建网站资产”绝不仅仅是初次投入的成本,而是基于长期稳定、合规和安全的持续性投入,其中核心取决于你选择了什么样的“地基”来承载你的业务,建站预算的构成与行业基准当你开始规划一个网站,最先面对的就是预算问题,一个常见的误区是只关注网站“看起来”的建造……

    2026-08-10
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注