`
vipbooks
  • 浏览: 148976 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类

Oracle学习笔记(5) 在PLSQL中使用游标获取数据

阅读更多
    这是第五章的学习笔记,学习完第四章的数据库操作和事务之后,开始要学习游标的使用了……,希望大家能多给俺一些支持啊!
    编程时使用的工具是PLSQL Developer 7.1.4

隐式游标
隐式游标的属性等在第四章笔记中已记录了一部分
如果要确保属性指向想要的SQL语句,那么就在SQL语句执行后,立即将属性值保存到一个本地变量中
用存储过程来实现这种效果:
先定义一个存储过程remove_from_emp ,用于从雇员中删除一个员工
在存储过程的参数中 in 表示输入,out 表示输出
create or replace procedure remove_from_emp(empno_in in employee.empno%type)
is
begin
   delete from employee where empno = empno_in;
   dbms_output.put_line('删除了' || sql%rowcount || '条记录!');
end;
/
-- 定义一个存储过程来调用存储过程remove_from_emp,并保存隐式游标的属性值
create or replace procedure show_emp_count is
   i_count integer;
   i_numfound pls_integer;
begin
   select count(*) into i_count from employee;
   -- 将属性值做一个快照
   i_numfound := sql%rowcount;
   -- 注意employee表中没有编号为99的员工
   -- 调用存储过程remove_from_emp
   remove_from_emp(1);
   -- 现在可以用前一条语句的属性值输出
   dbms_output.put_line(i_numfound);
end;
/

显式游标(PL/SQL块中使用显示游标的本个步骤:声明、打开、提取记录、关闭)
在程序包规范中声明一个游标类型(我们可以在PL/SQL块或者包的定义部分声明游标类型)
create or replace package types
is
type emp_cur5 is ref cursor;
end;
/
declare
   -- 定义一个不带参数的游标emp_cur1,游标的结果是employee表中员工的集合
   cursor emp_cur1 is select * from employee;
   -- 定义一个带参数的游标emp_cur2,游标的结果集是匹配由游标传递过来的员工编号的员工姓名和加入公司的时间
   cursor emp_cur2 (empno_in in number) is select name,hiredate from employee where empno = empno_in;
   -- 定义一个带有return 子句的游标,游标的结果集是员工编号为1的employee表中所有的列
   cursor emp_cur3 return employee%rowtype is select * from employee where empno = 1; 

如果想通过游标更新数据,必须在select 语句后加上for update 子句,
该select 语句涉及的所有行都会被锁住
如果是加上了for update of 列名,那么只有在for update 子句中引用了某个表的列时,
该表中的行才会被锁住,of 列表并不限制只能更改列给出的列,它只让我们知道要更改什么
可以在for update 子句后添加一个nowait 关键字,用于告诉Oracle如果表已经被其他用户
锁住,就不需要等待了,这样控制权会立即返回给我们的程序,如果没有nowait子句进程就
会阻塞,直到表可用(commit或rollback)为止
可以在Select into、Fetch into、Returning into子句中使用Bulk Collect将数据输出到集合中
   cursor emp_cur4 (empno_in in number) is select name,salary from employee where empno = empno_in for update;
   -- 应该总是将游标行提取到用%rowtype定义的记录中,这样更灵活(表字段改变了不需要更改fetch语句)
   emp_row1 employee%rowtype;
   -- 基于游标定义一个记录
   emp_row2 emp_cur2%rowtype;
   emp_row3 emp_cur3%rowtype;
   emp_row4 emp_cur4%rowtype;
   n_salary number(10,2);
   n_empno employee.empno%type := &员工编号:;
   
   -- 游标变量和ref cursor
   -- 定义ref cursor 类型的游标变量
   -- 创建一个强类型的引用游标类型
   type emp_ref_type1 is ref cursor return employee%rowtype;
   -- 创建一个弱类型的引用游标类型(弱类型的游标变量比强类型的游标变量更灵活)
   type emp_ref_type2 is ref cursor;
   -- 定义实际的游标变量
   emp_ref1 emp_ref_type1;
   emp_ref2 emp_ref_type2;
   -- 从Oracle9i 开始提供了一个名为sys_refcursor的预定义的Oracle系统游标,
   -- 它相当于弱类型游标,使用它不需要定义游标变量
   sys_cursor sys_refcursor;
   -- 定义一个行类型的集合
   type emp_table_type is table of employee%rowtype index by binary_integer;
   emp_table emp_table_type;
   type emp_info_type is record(name employee.name%type,job employee.job%type);
   emp_info emp_info_type;
begin

打开游标:open 显式游标名 (参数列表)
一旦打开了显式游标,就可以从游标中提取记录,直到没有记录留在游标中
打开游标时,PL/SQL就开始执行该游标的Select 查询,但是实际上并不返回任何行,
返回行的任务是由后面的Fetch(读取)…… into(赋值给)……  语句完成的:
fetch 游标名 into 记录或变量列表
   open emp_cur1;
   -- 提取记录
   -- 如果游标只返回一行可以用if、loop或for来判断获得数据,如果游标返回多行可以用loop或for来循环获得数据
   loop
      fetch emp_cur1 into emp_row1;
      exit when emp_cur1%notfound;
      dbms_output.put_line('员工' || emp_row1.name || '的工资是:' || emp_row1.salary);
   end loop;
   -- 关闭游标并释放资源
   close emp_cur1;
   -- 打开带参数的游标
   -- 游标for 循环能很好的简化游标的开发,我们不再需要声明记录,不再需要Open、Fetch和Close语句
   -- 也不再需要%found属性检测记录,一切Oracle隐式的帮我们完成了
   for emp_row2 in emp_cur2(n_empno) loop
      dbms_output.put_line('员工' || emp_row2.name || '加入公司的时间是 ' || emp_row2.hiredate);
   end loop;
   -- 打开带return 子句的游标
   open emp_cur3;
   fetch emp_cur3 into emp_row3;
   if emp_cur3%found then
      dbms_output.put_line('员工' || emp_row3.name || '其职位是' || emp_row3.job || ',加入公司的时间是 ' || emp_row3.hiredate);
   end if;
   close emp_cur3;
   -- 打开带for update 子句的游标,将指定编号的员工工资增加500元
   open emp_cur4(n_empno);
   fetch emp_cur4 into emp_row4;

where current of 游标名 子句能很容易的修改最近提取的数据行(也就是当前游标指向的位置),
这样的好处是,如果表表结构发生了改变,我们只需要更改Select语句的Where子句即可,而不
需要更新每个SQL语句
   if emp_cur4%found then
      update employee set salary = salary + 500 where current of emp_cur4; --returning salary into n_salary;
   end if;
   commit;
   n_salary := emp_row4.salary + 500;
   dbms_output.put_line('员工' || emp_row4.name || '原来的工资是' || emp_row4.salary || '元,增加工资后现在的工资是' || n_salary || '元');
   close emp_cur4;
   
   -- 打开强类型游标变量
   open emp_ref1 for select * from employee order by salary;
   -- 在游标变量中提取数据
   fetch emp_ref1 bulk collect into emp_table;
   for i in 1..emp_table.count loop
       dbms_output.put_line(emp_table(i).name || '   本月工资 ' || emp_table(i).salary);
   end loop;
   -- 关闭游标变量
   close emp_ref1;
   -- 打开弱类型游标变量
   open emp_ref2 for select name,job from employee;
   loop
      fetch emp_ref2 into emp_info;
      exit when emp_ref2%notfound;
      dbms_output.put_line(emp_info.name || '的工作是 ' || emp_info.job); 
   end loop;
   close emp_ref2;
   -- 打开Oracle系统游标
   open sys_cursor for select name,hiredate from employee order by hiredate desc;
   loop
      fetch sys_cursor into emp_info;
      exit when sys_cursor%notfound;
      dbms_output.put_line(emp_info.name || '加入公司的时间是 ' || emp_info.job); 
   end loop;
   close sys_cursor;
exception
   when NO_DATA_FOUND then dbms_output.put_line('查询不到员工编号为' || n_empno || '的员工!');
   when TOO_MANY_ROWS then dbms_output.put_line('数据完整性错误,员工编号' || n_empno || '重复!');
   when OTHERS then dbms_output.put_line('PL/SQL执行错误!' || sqlerrm);
end;
/
分享到:
评论
1 楼 guji528 2010-04-06  
写存储过程经常都会用到游标,总结得很全面

相关推荐

    oracle学习笔记(从入门到精通)

    压缩包主要包括15个文档,主要是本人学习oracle过程中的笔记,希望...08-PLSQL和游标结合学习笔记.txt 09-游标学习笔记.txt 10-重要的函数的学习笔记.txt 11-存储过程学习笔记.txt 12-触发器学习笔记.txt 13-pl编码.txt

    PLSQL学习笔记(1-7)

    本“PLSQL学习笔记”将逐步讲解这些概念,通过实例和练习帮助读者巩固理解,进一步提升在Oracle数据库开发中的技能。无论你是初学者还是有经验的开发者,这份笔记都能提供有价值的参考。通过深入学习和实践,你将...

    学习oracle笔记-PLSQL

    以下是一个简单的示例,展示了如何定义变量并在执行部分中使用它们: ```plsql DECLARE v_ename VARCHAR2(5); -- 定义一个字符串变量 BEGIN SELECT ename INTO v_ename FROM emp WHERE empno = &no; -- 执行部分 ...

    oracle plsql 菜鸟学习笔记

    通过本文,我们可以了解 Oracle PL/SQL 的基础知识点,包括变量命名规则、过程和函数的创建、PL/SQL 块结构、变量和常量、游标、异常处理、包的创建和使用、记录类型、输出信息等。这些知识点是 Oracle PL/SQL 编程...

    Oracle 10g 学习笔记

    │ Oracle学习笔记.pdf │ Oracle学习笔记.wps │ 安装Oracle后myEclipse不能正常使用.txt │ 手工配置listener.ora【避免出现ORA-12514错误】.txt │ 贴子树状态存储结构.jpg │ 贴子树状态存储结构.sql │ ├─01...

    oracle笔记二--plsql 编程.txt

    **标题**: oracle笔记二--plsql 编程 **描述**: oracleoracleoracleoracleoracleoracleoracleoracle(推测为占位符文本,无实际意义) **标签**: oracle **部分内容**: 在部分内容中提到了关于Oracle 10g的安装与...

    PLSQL 学习笔记

    声明游标后,可以使用FETCH语句获取当前行,然后在循环中使用。例如: ```sql DECLARE CURSOR c_emp IS SELECT * FROM employees; emp_rec employees%ROWTYPE; BEGIN OPEN c_emp; FETCH c_emp INTO emp_rec; ...

    ORACLE_PlSql-甲骨文学习笔记

    ### ORACLE_PlSql-甲骨文学习笔记 #### 一、创建表 ##### 创建表一 ```sql CREATE TABLE TABLE_NAME ( AAA INTEGER CONSTRAINT PK_TABLE_NAME PRIMARY KEY, BBB VARCHAR2(10) NOT NULL, DOB DATE, CCC VARCHAR...

    PLSQL笔记-从hello word到触发器,包,游标高级应用

    PLSQL,全称为Procedural Language/SQL,是Oracle数据库提供的结构化查询语言扩展,它结合了SQL(Structured Query Language)...通过学习这些笔记,你将能够掌握PLSQL的高级应用,从而在Oracle数据库开发中游刃有余。

    Oracle9i PLSQL 入门到精通读书笔记

    - 游标用于逐行处理SQL查询结果,通常在循环中使用。 - DECLARE语句中声明游标,OPEN语句打开游标,FETCH获取数据,CLOSE关闭游标。 7. **异常处理** - 使用EXCEPTION部分可以捕获并处理运行时错误,如NO_DATA_...

    PLSQL学习笔记

    这些只是PL/SQL学习笔记的部分内容,实际使用中还会涉及游标、子程序、异常处理、动态SQL等多个方面。掌握PL/SQL能帮助开发者更有效地管理和操作Oracle数据库,实现复杂的数据处理任务。通过不断实践和学习,你可以...

    sql和plsql学习笔记

    - 数据查询:SELECT语句用于从数据库中获取数据,可配合WHERE子句进行条件筛选,GROUP BY用于分组,HAVING用于分组后的条件筛选,ORDER BY用于排序。 - 插入数据:INSERT语句用于向表中插入新记录。 - 更新数据:...

    oracle经典笔记

    《Oracle_02.pdf》至《Oracle_04.pdf》可能进一步深入到Oracle数据库的高级特性,比如表空间管理、数据库备份与恢复策略、性能优化、安全性设置等,这些是数据库管理员在实际工作中必须掌握的关键技能。 最后,...

    Oracle_10g_plsql实战笔记.doc

    ### Oracle 10g PL/SQL 实战笔记关键知识点解析 #### 一、PL/SQL 概述 - **PL/SQL** (Procedural Language for SQL) 是 Oracle 数据库的一种扩展,它允许用户在 SQL 的基础上进行更复杂的程序设计。 - **特性**: ...

    达内的plsql笔记和代码

    PLSQL,全称为Procedural Language/Structured Query Language,是Oracle数据库系统中用于操作和管理数据的一种编程语言。它是SQL的扩展,增加了程序化的元素,如循环、条件语句和子程序,使得数据库管理和开发更加...

    plsql学习笔记整理.docx

    PL/SQL 学习笔记总结 PL/SQL 是 Oracle 在标准 SQL 语言上的扩展,提供了更多的编程功能,例如定义变量和常量、使用条件语句和循环语句、例外处理等。使用 PL/SQL 可以提高开发效率和数据库性能。 PL/SQL 的优点 ...

    Java3相关课程系列笔记之三PLSQL学习笔记.doc

    本篇笔记主要围绕Java3相关课程中的PL/SQL部分进行深入讲解,由薛海璐老师主讲,全面涵盖了PL/SQL的基础概念、程序结构、运行过程以及变量和数据类型等核心知识点。 1、PL/SQL简介 PL/SQL是Oracle数据库的一种过程...

Global site tag (gtag.js) - Google Analytics