`
心动音符
  • 浏览: 336975 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

快速掌握Oracle数据库游标的使用方法

阅读更多
 显式游标

  当查询返回结果超过一行时,就需要一个显式游标,此时用户不能使用select into语句。PL/SQL管理隐式游标,当查询开始时隐式游标打开,查询结束时隐式游标自动关闭。显式游标在PL/SQL块的声明部分声明,在执行部分或异常处理部分打开,取出数据,关闭。

  使用游标

  这里要做一个声明,我们所说的游标通常是指显式游标,因此从现在起没有特别指明的情况,我们所说的游标都是指显式游标。要在程序中使用游标,必须首先声明游标。

  声明游标

  语法:

  CURSOR cursor_name IS select_statement;


  在PL/SQL中游标名是一个未声明变量,不能给游标名赋值或用于表达式中。

  例:
  DELCARE

  CURSOR C_EMP IS SELECT empno,ename,salary

  FROM emp

  WHERE salary>2000

  ORDER BY ename;

  ........

  BEGIN
  
在游标定义中SELECT语句中不一定非要表可以是视图,也可以从多个表或视图中选择的列,甚至可以使用*来选择所有的列 。

  打开游标

  使用游标中的值之前应该首先打开游标,打开游标初始化查询处理。打开游标的语法是:

  
OPEN cursor_name。


  cursor_name是在声明部分定义的游标名

  例:

  OPEN C_EMP; 关闭游标。

  语法:

  
CLOSE cursor_name


  例:

  CLOSE C_EMP; 从游标提取数据。从游标得到一行数据使用FETCH命令。每一次提取数据后,游标都指向结果集的下一行。语法如下:

  
FETCH cursor_name INTO variable[,variable,...]


  对于SELECT定义的游标的每一列,FETCH变量列表都应该有一个变量与之相对应,变量的类型也要相同。

  例:
  SET SERVERIUTPUT ON

  DECLARE

  v_ename EMP.ENAME%TYPE;

  v_salary EMP.SALARY%TYPE;

  CURSOR c_emp IS SELECT ename,salary FROM emp;

  BEGIN

  OPEN c_emp;

  FETCH c_emp INTO v_ename,v_salary;

  DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename ||'is'|| v_salary);

  FETCH c_emp INTO v_ename,v_salary;

  DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename ||'is'|| v_salary);

  FETCH c_emp INTO v_ename,v_salary;

  DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename ||'is'|| v_salary);

  CLOSE c_emp;

  END
 
 这段代码无疑是非常麻烦的,如果有多行返回结果,可以使用循环并用游标属性为结束循环的条件,以这种方式提取数据,程序的可读性和简洁性都大为提高,下面我们使用循环重新写上面的程序:
  SET SERVERIUTPUT ON

  DECLARE

  v_ename EMP.ENAME%TYPE;

  v_salary EMP.SALARY%TYPE;

  CURSOR c_emp IS SELECT ename,salary FROM emp;

  BEGIN

  OPEN c_emp;

  LOOP

  FETCH c_emp INTO v_ename,v_salary;

  EXIT WHEN c_emp%NOTFOUND;

  DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename ||'is'|| v_salary);

  END
  
记录变量

  定义一个记录变量使用TYPE命令和%ROWTYPE,关于%ROWsTYPE的更多信息请参阅相关资料。

  记录变量用于从游标中提取数据行,当游标选择很多列的时候,那么使用记录比为每列声明一个变量要方便得多。

  当在表上使用%ROWTYPE并将从游标中取出的值放入记录中时,如果要选择表中所有列,那么在SELECT子句中使用*比将所有列名列出来要得多。

  例:
  SET SERVERIUTPUT ON

  DECLARE

  R_emp EMP%ROWTYPE;

  CURSOR c_emp IS SELECT * FROM emp;

  BEGIN

  OPEN c_emp;

  LOOP

  FETCH c_emp INTO r_emp;

  EXIT WHEN c_emp%NOTFOUND;

  DBMS_OUT.PUT.PUT_LINE('Salary of Employee'||r_emp.ename||'is'|| r_emp.salary);

  END LOOP;

  CLOSE c_emp;

  END;

  %ROWTYPE也可以用游标名来定义,这样的话就必须要首先声明游标:

  SET SERVERIUTPUT ON

  DECLARE

  CURSOR c_emp IS SELECT ename,salary FROM emp;

  R_emp c_emp%ROWTYPE;

  BEGIN

  OPEN c_emp;

  LOOP

  FETCH c_emp INTO r_emp;

  EXIT WHEN c_emp%NOTFOUND;

  DBMS_OUT.PUT.PUT_LINE('Salary of Employee'

  ||r_emp.ename||'is'|| r_emp.salary);

  END LOOP;

  CLOSE c_emp;

  END;
 
 带参数的游标

  与存储过程和函数相似,可以将参数传递给游标并在查询中使用。这对于处理在某种条件下打开游标的情况非常有用。它的语法如下:
  CURSOR cursor_name[(parameter[,parameter],...)] IS select_statement;
  
定义参数的语法如下:

  
Parameter_name [IN] data_type[{:=|DEFAULT} value]


  与存储过程不同的是,游标只能接受传递的值,而不能返回值。参数只定义数据类型,没有大小。

  另外可以给参数设定一个缺省值,当没有参数值传递给游标时,就使用缺省值。游标中定义的参数只是一个占位符,在别处引用该参数不一定可靠。

  在打开游标时给参数赋值,语法如下:

 
 OPEN cursor_name[value[,value]....];

  参数值可以是文字或变量。

  例:
  DECALRE

  CURSOR c_dept IS SELECT * FROM dept ORDER BY deptno;

  CURSOR c_emp (p_dept VARACHAR2) IS

  SELECT ename,salary

  FROM emp

  WHERE deptno=p_dept

  ORDER BY ename

  r_dept DEPT%ROWTYPE;

  v_ename EMP.ENAME%TYPE;

  v_salary EMP.SALARY%TYPE;

  v_tot_salary EMP.SALARY%TYPE;

  BEGIN

  OPEN c_dept;

  LOOP

  FETCH c_dept INTO r_dept;

  EXIT WHEN c_dept%NOTFOUND;

  DBMS_OUTPUT.PUT_LINE

  ('Department:'|| r_dept.deptno||'-'||r_dept.dname);

  v_tot_salary:=0;

  OPEN c_emp(r_dept.deptno);

  LOOP

  FETCH c_emp INTO v_ename,v_salary;

  EXIT WHEN c_emp%NOTFOUND;

  DBMS_OUTPUT.PUT_LINE

  ('Name:'|| v_ename||' salary:'||v_salary);

  v_tot_salary:=v_tot_salary+v_salary;

  END LOOP;

  CLOSE c_emp;

  DBMS_OUTPUT.PUT_LINE

  ('Toltal Salary for dept:'|| v_tot_salary);

  END LOOP;

  CLOSE c_dept;

  END;
 
 游标FOR循环

  在大多数时候我们在设计程序的时候都遵循下面的步骤:

  1、打开游标。

  2、开始循环。

  3、从游标中取值。

  4、那一行被返回。

  5、处理。

  6、关闭循环。

  7、关闭游标。

  可以简单的把这一类代码称为游标用于循环。但还有一种循环与这种类型不相同,这就是FOR循环,用于FOR循环的游标按照正常的声明方式声明,它的优点在于不需要显式的打开、关闭、取数据,测试数据的存在、定义存放数据的变量等等。游标FOR循环的语法如下:
  FOR record_name IN

  (corsor_name[(parameter[,parameter]...)]

  | (query_difinition)

  LOOP

  statements

  END LOOP;

  下面我们用for循环重写上面的例子:

  DECALRE

  CURSOR c_dept IS SELECT deptno,dname FROM dept ORDER BY deptno;

  CURSOR c_emp (p_dept VARACHAR2) IS

  SELECT ename,salary

  FROM emp

  WHERE deptno=p_dept

  ORDER BY ename

  v_tot_salary EMP.SALARY%TYPE;

  BEGIN

  FOR r_dept IN c_dept LOOP

  DBMS_OUTPUT.PUT_LINE

  ('Department:'|| r_dept.deptno||'-'||r_dept.dname);

  v_tot_salary:=0;

  FOR r_emp IN c_emp(r_dept.deptno) LOOP

  DBMS_OUTPUT.PUT_LINE

  ('Name:' || v_ename || 'salary:' || v_salary);

  v_tot_salary:=v_tot_salary+v_salary;

  END LOOP;

  DBMS_OUTPUT.PUT_LINE

  ('Toltal Salary for dept:'|| v_tot_salary);

  END LOOP;

  END;
  
在游标FOR循环中使用查询

  在游标FOR循环中可以定义查询,由于没有显式声明所以游标没有名字,记录名通过游标查询来定义。
  DECALRE

  v_tot_salary EMP.SALARY%TYPE;

  BEGIN

  FOR r_dept IN (SELECT deptno,dname FROM dept ORDER BY deptno) LOOP

  DBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname);

  v_tot_salary:=0;

  FOR r_emp IN (SELECT ename,salary

  FROM emp

  WHERE deptno=p_dept

  ORDER BY ename) LOOP

  DBMS_OUTPUT.PUT_LINE('Name:'|| v_ename||' salary:'||v_salary);

  v_tot_salary:=v_tot_salary+v_salary;

  END LOOP;

  DBMS_OUTPUT.PUT_LINE('Toltal Salary for dept:'|| v_tot_salary);

  END LOOP;

  END;
  
游标中的子查询

  语法如下:
  CURSOR C1 IS SELECT * FROM emp

  WHERE deptno NOT IN (SELECT deptno

  FROM dept

  WHERE dname!='ACCOUNTING');
 
 可以看出与SQL中的子查询没有什么区别。

  游标中的更新和删除

  在PL/SQL中依然可以使用UPDATE和DELETE语句更新或删除数据行。显式游标只有在需要获得多行数据的情况下使用。PL/SQL提供了仅仅使用游标就可以执行删除或更新记录的方法。

  UPDATE或DELETE语句中的WHERE CURRENT OF子串专门处理要执行UPDATE或DELETE操作的表中取出的最近的数据。要使用这个方法,在声明游标时必须使用FOR UPDATE子串,当对话使用FOR UPDATE子串打开一个游标时,所有返回集中的数据行都将处于行级(ROW-LEVEL)独占式锁定,其他对象只能查询这些数据行,不能进行UPDATE、DELETE或SELECT...FOR UPDATE操作。

  语法:
  FOR UPDATE [OF [schema.]table.column[,[schema.]table.column]..

  [nowait]

  在多表查询中,使用OF子句来锁定特定的表,如果忽略了OF子句,那么所有表中选择的数据行都将被锁定。如果这些数据行已经被其他会话锁定,那么正常情况下ORACLE将等待,直到数据行解锁。

  在UPDATE和DELETE中使用WHERE CURRENT OF子串的语法如下:

  WHERE{CURRENT OF cursor_name|search_condition}
  例:

  DELCARE

  CURSOR c1 IS SELECT empno,salary

  FROM emp

  WHERE comm IS NULL

  FOR UPDATE OF comm;

  v_comm NUMBER(10,2);

  BEGIN

  FOR r1 IN c1 LOOP

  IF r1.salary<500 THEN

  v_comm:=r1.salary*0.25;

  ELSEIF r1.salary<1000 THEN

  v_comm:=r1.salary*0.20;

  ELSEIF r1.salary<3000 THEN

  v_comm:=r1.salary*0.15;

  ELSE

  v_comm:=r1.salary*0.12;

  END IF;

  UPDATE emp;

  SET comm=v_comm

  WHERE CURRENT OF c1l;

  END LOOP;

  END
分享到:
评论

相关推荐

    快速掌握Oracle数据库中的Copy命令

    Oracle数据库中的Copy命令是SQL*Plus提供的一种便捷的数据复制工具,尤其对于DBA来说,它在处理表间数据复制任务时具有较高的效率。Copy命令允许用户在同一个数据库的不同表之间,甚至不同服务器的数据库之间复制...

    oracle数据库从入门到精通.pdf

    文档《oracle数据库从入门到精通.pdf》详细地介绍了Oracle数据库的基础知识和高级操作,使得学习者能够从基础的表空间创建到存储过程的编写,以及游标的应用等高级特性有深入理解和掌握。 首先,文档指出了创建表...

    oracle数据库操作手册

    本操作手册将深入探讨Oracle数据库的核心概念、安装配置、管理维护以及SQL查询等多个方面,帮助用户全面理解和掌握Oracle数据库的操作。 1. **Oracle数据库核心概念** - **数据库实例与数据库**:Oracle数据库实例...

    ORACLE 数据库入门教程

    本教程旨在为初学者提供一个全面的Oracle数据库入门指南,帮助你快速掌握Oracle的基础知识和操作技能。 一、Oracle数据库简介 Oracle数据库是由甲骨文公司开发的一款面向企业级的高性能、高可靠性的数据库系统。它...

    多个ORACLE 游标+SQL 游标 小例子+帮助文档

    Oracle数据库中的游标主要分为两种类型:隐式游标和显式游标。隐式游标是Oracle自动管理的,每次执行DML语句(INSERT、UPDATE、DELETE)时都会使用。而显式游标则需要我们手动声明和管理,适用于更复杂的逻辑处理。 ...

    oracle官方数据库教程

    Oracle数据库是全球广泛使用的大型关系型数据库管理系统,尤其在企业级应用中占据重要地位。...通过深入学习并实践这些内容,你将能够熟练掌握Oracle数据库的管理和开发技能,为未来的职业生涯奠定坚实基础。

    oracle数据库速学

    以上就是Oracle数据库速学的一些关键知识点,这些内容将帮助初学者快速入门并逐步深入理解Oracle数据库。在实际学习过程中,结合“数据库.txt”中的资料,理论与实践相结合,相信你会对Oracle有更全面的认识。

    Oracle数据库系统应用实例集锦与编程技巧

    熟悉其语法特性,掌握异常处理和游标使用,能实现复杂业务逻辑。 12. **数据库升级与迁移**:Oracle提供了一系列工具和技术进行版本升级和跨平台迁移,如Data Pump、DBUA等,确保数据完整无损地转移到新环境。 ...

    21天自学速成 Oracle 数据库 电子书

    《21天自学速成 Oracle 数据库》是一本旨在帮助初学者快速掌握Oracle数据库系统核心概念和技术的电子书籍。在21天的学习计划中,它将带你逐步深入了解Oracle的各个方面,从基础安装到高级管理技巧,助你在短时间内...

    零基础学习oracle数据库

    本教程旨在帮助那些没有任何数据库背景的人快速理解和掌握Oracle的基本概念和操作。 【备课笔记】部分可能包含以下知识点: 1. 数据库基础知识:介绍什么是数据库,以及为什么我们需要数据库,特别是Oracle数据库...

    Oracle 数据库学习教程

    Oracle教程通过系统性的讲解,帮助读者掌握Oracle数据库的各项技能,从入门到高级特性,从理论到实际应用。Oracle和Sun的合并背景信息提供了对Oracle公司发展及其产品战略的宏观认识,特别是其在云计算领域的布局和...

    Excel表的Oracle数据库插入工具

    此外,如果Excel文件非常大,还可以考虑先将数据导出为CSV文件,然后通过SQL*Loader等工具快速导入到Oracle数据库。 总之,将Excel数据插入Oracle数据库涉及的关键技术点包括:Excel文件的读取(如使用pandas)、...

    oracle数据库开发工具

    Oracle数据库是全球广泛使用的大型关系型数据库管理系统,其强大的功能和高效的数据处理能力深受企业和开发者喜爱。在Oracle数据库的开发过程中,PL/SQL(Procedural Language/Structured Query Language)是一种不...

    ORACLE数据库教程下载

    本教程将全面介绍Oracle数据库的核心概念、安装配置、管理操作以及高级特性,帮助初学者快速掌握Oracle数据库的基础知识和实战技能。 一、Oracle数据库系统概述 Oracle数据库系统是一个大型分布式数据库管理系统,...

    Oracle11g 数据库中文 文档

    8. **高可用性与故障恢复**:这部分会介绍RAC(实时应用集群)、数据守护、闪回技术等,这些都是保证Oracle数据库高可用性和快速故障恢复的关键特性。 9. **数据迁移与升级**:文档会提供从旧版本Oracle数据库升级...

    oracle数据库21个入门教程

    这个"Oracle数据库21个入门教程"很可能是为初学者设计的一系列学习资源,帮助他们快速掌握Oracle数据库的基本概念、操作和管理技巧。下面我们将深入探讨Oracle数据库的一些关键知识点。 1. **数据库概念**:数据库...

    百千Oracle课程--oracle数据库初学者

    在"百千Oracle课程"中,每个章节都可能包含详细的讲解、实例演示和课后练习,以确保学习者能够逐步掌握Oracle数据库的核心技能。通过这个课程,初学者不仅能了解到Oracle的基本原理,还能获得实际操作经验,为进一步...

Global site tag (gtag.js) - Google Analytics