专业汉语词典知识平台,分享汉字词语知识、历史文学知识解答!

励北网
励北网

oracle游标的使用,oracle游标详解

来源:小易整编  作者:小易  发布时间:2022-12-26 04:36
摘要:oracle游标的使用,oracle游标详解。在Oracle数据库开发中,有时需要对不同的数据行做不同的处理,游标提供了一种从表中检索数据并进行操作的灵活手段,游标主要用在服务器上,处理由客户端发送给服务器端的SQL语句,或是批处理、存储过...

oracle游标的使用,oracle游标详解。在Oracle数据库开发中,有时需要对不同的数据行做不同的处理,游标提供了一种从表中检索数据并进行操作的灵活手段,游标主要用在服务器上,处理由客户端发送给服务器端的SQL语句,或是批处理、存储过程、触发器中的数据处理请求。游标的作用相当于指针,通过游标PL/SQL程序可以一次处理查询结果集中的一行,并可以对该行数据执行特定操作,从而为用户在处理数据的过程中提供了很大方便。

oracle游标的使用,oracle游标详解

在Oracle中,通过游标操作数据主要使用显式游标和隐式游标,另外,还有具有引用类型的ref游标,下面将分别介绍。

1 显式游标

1.1 显式游标介绍

显式游标由用户自己定义和操作游标,通常所说的游标都是指显式游标。

游标的使用分成以下4个步骤:

1.1.1 声明游标

在DECLARE部分按以下格式声明游标:

CURSOR 游标名[(参数1 数据类型[,参数2 数据类型...])]

IS SELECT 语句;

参数是可选部分,所定义的参数可以出现在SELECT语句的WHERE子句中。如果定义了参数,则必须在打开游标时传递相应的实际参数。

1.1.2 打开游标

在可执行部分,按以下格式打开游标:

OPEN 游标名[(实际参数1[,实际参数2])];

打开游标时,SELECT语句的查询结果就被传送到了游标工作区。

1.1.3 提取数据

在可执行部分,按以下格式将游标工作区中的数据提取到变量中。提取操作必须在打开游标之后进行。

FETCH 游标名 INTO 变量名1[,变量名2...];

FETCH 游标名 INTO 记录变量;

游标打开后有一个指针指向数据区,FETCH语句一次返回指针所指的一样数据,要返回多行需重复执行,可以使用循环语句来实现。控制循环可以通过判断游标的属性来进行。

对以上两种格式进行说明:

第一种格式中的变量是用来从游标中接收数据的变量,需要事先定义。变量的个数与类型应与SELECT语句中的字段变量的个数与类型一致。

第二种格式一次将一行数据取到记录变量中,需使用%ROWTYPE事先定义记录变量,这种形式使用起来比较方便,不必分别定义和使用多个变量。(定义记录变量方法:变量名 表名|游标名%ROWTYPE)

1.1.4 关闭游标

CLOSE 游标名;

显示游标打开后,必须显示地关闭。游标一旦关闭,游标占用的资源就被释放,游标变成无效,必须重新打开才能使用。

1.2 显式游标属性

通过游标的属性可以获取SQL的执行结果以及游标的状态信息:

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

    %notfound:布尔型,与%found属性相反;

    %rowcount:整数,获得FETCH语句返回的行数;

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

1.3 显式游标举例

1)通过变量存储游标结果,将变量写在条件中,也可以参数的形式放在游标名称后面,即cursor cur_emp(pi_deptno in number)

declare  v_deptno emp.deptno%type := 30;  cursor cur_emp is    select empno, ename, sal from emp where deptno = v_deptno;  v_empno emp.empno%type;  v_ename emp.ename%type;  v_sal   emp.sal%type;begin  -- 为便于查看游标属性,将其打印出来,实际实用中不必打印  if cur_emp%isopen  then    dbms_output.put_line('游标已打开.....');  else    dbms_output.put_line('游标未打开.....');  end if;  open cur_emp;  fetch cur_emp --游标一次取一行数据,若返回多行,需循环处理    into v_empno, v_ename, v_sal;  dbms_output.put_line('工号:' || v_empno || ' 姓名:' || v_ename || ' 工资:' ||                       v_sal);  if cur_emp%found  then    dbms_output.put_line('还有数据行待处理....');  end if;  close cur_emp;end;

2)通过record类型存储游标结果

declare  v_deptno emp.deptno%type := 30;  cursor cur_emp is    select empno, ename, sal from emp where deptno = v_deptno;  type typ_emp is record(    empno emp.empno%type,    ename emp.ename%type,    sal   emp.sal%type);  v_emp typ_emp;begin  if cur_emp%isopen  then    dbms_output.put_line('游标已打开.....');  else    dbms_output.put_line('游标未打开.....');  end if;  open cur_emp;  fetch cur_emp --游标一次取一行数据,若返回多行,需循环处理    into v_emp;  dbms_output.put_line('工号:' || v_emp.empno || ' 姓名:' || v_emp.ename ||                       ' 工资:' || v_emp.sal);  if cur_emp%found  then    dbms_output.put_line('还有数据行待处理....');  end if;  close cur_emp;end;

3)通过%rowtype类型存储游标结果

declare  v_deptno emp.deptno%type := 30;  cursor cur_emp is    select empno, ename, sal from emp where deptno = v_deptno;  v_emp cur_emp%rowtype;begin  if cur_emp%isopen  then    dbms_output.put_line('游标已打开.....');  else    dbms_output.put_line('游标未打开.....');  end if;  open cur_emp;  fetch cur_emp --游标一次取一行数据,若返回多行,需循环处理    into v_emp;  dbms_output.put_line('工号:' || v_emp.empno || ' 姓名:' || v_emp.ename ||                       ' 工资:' || v_emp.sal);  if cur_emp%found  then    dbms_output.put_line('还有数据行待处理....');  end if;  close cur_emp;end;

4)由于逐行处理游标的获取的数据行,如果结果集比较大,由于语句的执行在SQL引擎和PL/SQL引擎上下文切换比较频繁,性能会很差,这时可考虑使用bulk collect批量处理结果集

declare    cursor cur_emp is      select empno, ename, sal from emp;      type typ_emp is table of cur_emp%rowtype;    v_emp typ_emp;  begin    open cur_emp;      fetch cur_emp bulk collect      into v_emp;      dbms_output.put_line('获取的数据行数:' || v_emp.count);      for r in v_emp.first .. v_emp.last    loop      dbms_output.put_line('工号:' || v_emp(r).empno || ' 姓名:' || v_emp(r).ename ||                           ' 工资:' || v_emp(r).sal);    end loop;      close cur_emp;  end;

5)当数据量很大的时候,将整个结果集作为一批进行处理,仍然会很耗时,这时就需要对结果集进行分段处理,比如每次处理50000条,可使用limit限制一次获取的数据行数

declare  cursor cur_emp is    select empno, ename, sal from emp;  type typ_emp is table of cur_emp%rowtype;  v_emp typ_emp;begin  open cur_emp;  loop    fetch cur_emp bulk collect      into v_emp limit 4;      exit when v_emp.count = 0;      dbms_output.put_line('获取的数据行数:' || v_emp.count);      for r in v_emp.first .. v_emp.last    loop      dbms_output.put_line('工号:' || v_emp(r).empno || ' 姓名:' || v_emp(r)                           .ename || ' 工资:' || v_emp(r).sal);    end loop;    end loop;  close cur_emp;end;

2 隐式游标

2.1 隐式游标介绍

在执行一个SQL语句时,Oracle会自动创建一个隐式游标,这个游标是内存中处理该语句的工作区域,隐式游标主要是DML语句的执行结果。

2.2 隐式游标属性

隐式游标和显示游标属性相似,只不过在其前面加上SQL:

sql%found:布尔型,值为TRUE代表插入、删除、更新或单行查询操作成功;

sql%notfound:布尔型,与sql%found属性相反;

sql%rowcount:整数,代表DML语句成功执行的行数;

sql%isopen:布尔型,DML执行过程中为真,结束后为假;

2.3 隐式游标举例

1)DML语句默认即隐式游标

declare  v_deptno emp.deptno%type := 90;  v_cnt   number;begin  update emp set sal = sal*1.2 where deptno = v_deptno;  v_cnt := sql%rowcount;  if v_cnt > 0  then    dbms_output.put_line('更新成功....更新的记录数为:'||v_cnt);    commit;  else    rollback;    dbms_output.put_line('更新不成功....更新的记录数为:'||v_cnt);  end if;end;

2)FOR ... LOOP循环语句也可是隐式游标

begin  for rec in (select * from emp)  loop    dbms_output.put_line('工号:' || rec.empno || ' 姓名:' || rec.ename ||                         ' 工资:' || rec.sal);  end loop;end;

3 动态游标

3.1 动态游标介绍

定义游标类型语句:

TYPE 游标类型名 REF CURSOR;

声明游标变量语句:

游标变量名游标类型名;

在可执行部分可以如下形式打开一个动态游标:

OPEN 游标变量名 FOR 查询语句字符串;

3.2 示例

declare  type cur is ref cursor;  v_cur cur;  type typ_emp is record(    empno emp.empno%type,    ename emp.ename%type,    sal   emp.sal%type);  v_emp typ_emp;  --v_sql varchar2(200) := 'select empno,ename,sal from emp';begin  --open v_cur for v_sql;  open v_cur for    select empno, ename, sal from emp;  loop    fetch v_cur      into v_emp;      exit when v_cur%notfound;      dbms_output.put_line('工号:' || v_emp.empno || ' 姓名:' || v_emp.ename ||                         ' 工资:' || v_emp.sal);    end loop;  close v_cur;end;

以上,就是关于游标的简单介绍,希望可以帮到大家,谢谢。


本文地址:百科问答频道 https://www.neebe.cn/wenda/886373.html,易企推百科一个免费的知识分享平台,本站部分文章来网络分享,本着互联网分享的精神,如有涉及到您的权益,请联系我们删除,谢谢!


百科问答
小编:小易整编
相关文章相关阅读
  • db2数据库详解,db2和oracle的区别

    db2数据库详解,db2和oracle的区别

    db2数据库详解,db2和oracle的区别概述DB2是IBM一种分布式数据库解决方案。说简单点:DB2就是IBM开发的一种大型关系型数据库平台。DB2不仅是一种移动计算基础设施,还是一个完整的环境,包含了构建、部署和支持强大的电子商务应用...

  • oracle存储过程是什么,oracle存储过程详解

    oracle存储过程是什么,oracle存储过程详解

    oracle存储过程是什么,oracle存储过程详解1、定义所谓存储过程(StoredProcedure),就是一组用于完成特定数据库功能的SQL语句集,该SQL语句集经过编译后存储在数据库系统中。在使用时候,用户通过指定已经定义的存储过程...

  • oracle 存储过程的基本语法

    oracle 存储过程的基本语法

    oracle存储过程oracle存储过程的很多语法可能大多数朋友并不是很了解,下面就来简单介绍几个比较常用的。oracle存储过程的基本语法1.基本结构CREATEORREPLACEPROCEDURE存储过程名字(参...

  • Oracle系统(Oracle数据库详解)

    Oracle系统(Oracle数据库详解)

    Oracle系统(Oracle数据库详解)什么是ORACLE?ORACLE数据库系统是美国ORACLE公(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构的数据库之一...

  • listagg函数用法,详解oracle函数listagg

    listagg函数用法,详解oracle函数listagg

    listagg函数用法,详解oracle函数listagg在工作中经常会遇到这样的问题:当需要把某一些查询到的结果合并并插入到数据库中的某一行时,会变得很麻烦。在某些情况下,我们可能可以借助诸如java、C等编程语言帮我们解决这样的问题,但...

  • 怎么卸载oracle,完全卸载oracle方法(超详细)

    怎么卸载oracle,完全卸载oracle方法(超详细)

    怎么卸载oracle,完全卸载oracle方法(超详细)进入服务找到Oracle开头的服务将这些服务全部停止Step1.点击开始菜单找到Oracle,然后点击Oracle安装产品,再点击UniversalInstallerStep2.点击之...

  • oracle adg介绍,adg搭建指南

    oracle adg介绍,adg搭建指南

    oracleadg介绍,adg搭建指南作为oracle数据库提供的一种容灾方式,ADG在我们日常生产中还是比较常见的,如何更快更好的搭建一套ADG,也是一个DBA需要掌握的基本技能。下面是一次在实际搭建过程中整理的操作步骤。可以供大家参考。...

  • oracle索引创建,oracle索引详解

    oracle索引创建,oracle索引详解

    oracle索引创建,oracle索引详解一、管理索引-原理介绍索引是用于加速数据存取的数据对象。合理的使用索引可以大大降低i/o次数,从而提高数据访问性能。索引有很多种我们主要介绍常用的几种:为什么添加了索引后,会加快查询速度呢?二、创建...

  • 周排行
  • 月排行
  • 年排行

精彩推荐