`

精通Oracle10编程SQL(9)使用游标

阅读更多
/*
 *使用游标
 */
--显示游标
--在显式游标中使用FETCH...INTO语句
DECLARE
   CURSOR emp_cursor is 
      select ename,sal from emp where deptno=1;
   v_ename emp.ename%TYPE;
   v_sal emp.sal%TYPE;
begin
   open emp_cursor;
   loop
      fetch emp_cursor into v_ename,v_sal;
      exit when emp_cursor%NOTFOUND;
      DBMS_OUTPUT.put_line(v_ename||':'||v_sal);
   end loop;
   close emp_cursor;
END;

SELECT * FROM emp;

--在显示游标中,使用FETCH...BULK COLLECT INTO语句提取所有数据
DECLARE
  CURSOR emp_cursor is
     select ename from emp where deptno=1;
  type ename_table_type is table of varchar2(10);
  ename_table ename_table_type;
begin
  open emp_cursor;
  fetch emp_cursor bulk collect into ename_table;
  for i in 1..ename_table.count loop
     dbms_output.put_line(ename_table(i));
  end loop;
  close emp_cursor;
END;

--在显示游标中使用FETCH...BULK COLLECT INTO ..LIMIT语句提取部分数据
--下面以每次提取5行数据为例,说明使用LIMIT子句限制行的方法
DECLARE
   TYPE name_array_type is varray(5) of varchar2(10);
   name_array name_array_type;
   cursor emp_cursor is select ename from emp;
   rows int:=5;
   v_count int:=0;
BEGIN
   OPEN emp_cursor;
   loop
      fetch emp_cursor bulk collect into name_array limit rows;
      dbms_output.put('雇员名:');
      DBMS_OUTPUT.put_line('影响行数'||emp_cursor%ROWCOUNT);
      dbms_output.put_line(v_count);
      for i in 1..(emp_cursor%ROWCOUNT-v_count) loop
         dbms_output.put(name_array(i)||' ');
      end loop;
      dbms_output.new_line;
      v_count:=emp_cursor%ROWCOUNT;
      EXIT WHEN emp_cursor%NOTFOUND;
  END LOOP;
  CLOSE emp_cursor;
END;

--使用游标属性
DECLARE
   CURSOR emp_cursor is select ename from emp where deptno=1;
   TYPE ename_table_type is table of varchar2(10);
   ename_table ename_table_type;
BEGIN
   if not emp_cursor%ISOPEN THEN  --如果游标未打开,则打开游标
      open emp_cursor;
   end if;
   fetch emp_cursor bulk collect into ename_table;
   dbms_output.put_line('提取的总计行数:'||emp_cursor%ROWCOUNT);  --显示总计行数
   close emp_cursor;
END;

--基于游标定义记录变量
DECLARE
  CURSOR emp_cursor is select ename,sal from emp;
  emp_record emp_cursor%ROWTYPE;
begin
  open emp_cursor;
  loop
     fetch emp_cursor into emp_record;
     exit when emp_cursor%NOTFOUND;
     dbms_output.put_line('雇员名:'||emp_record.ename||',雇员工资:'||emp_record.sal);
  end loop;
  close emp_cursor;
end;

--参数游标
--参数游标是指带有参数的游标,定义参数游标时,需要指定参数名及其数据类型
--注意:定义参数游标时,游标参数只能指定数据类型,而不能指定长度。另外,定义参数游标时,一定要在游标子查询的WHERE子句中引用该参数,否则失去了定义参数游标的意义
DECLARE
   CURSOR emp_cursor(no NUMBER) IS 
      SELECT ename from emp where deptno=no;
   v_ename emp.ename%TYPE;
begin
   open emp_cursor(1);
   loop
     fetch emp_cursor into v_ename;
     exit when emp_cursor%NOTFOUND;
     dbms_output.put_line(v_ename);
   end loop;
   close emp_cursor;
end;

--使用游标更新或删除数据
--使用游标更新数据
DECLARE
  CURSOR emp_cursor is 
     select ename,sal from emp for update;
  v_ename emp.ename%TYPE;
  v_oldsal emp.ename%TYPE;
begin
  open emp_cursor;
  loop
     fetch emp_cursor into v_ename,v_oldsal;
     exit when emp_cursor%NOTFOUND;
     if v_oldsal<1000 then
        update emp set sal=sal+100 where current of emp_cursor;
     end if;
  end loop;
  close emp_cursor;
end;

select * from emp;

--使用游标删除数据
--下面以解雇部门30的所有雇员为例,说明使用显式游标删除数据的方法
DECLARE
  CURSOR emp_cursor is 
     select ename,sal,deptno from emp for update;
  v_ename emp.ename%TYPE;
  v_oldsal emp.sal%TYPE;
  v_deptno emp.deptno%TYPE;
begin
  OPEN emp_cursor;
  loop
     fetch emp_cursor into v_ename,v_oldsal,v_deptno;
     exit when emp_cursor%NOTFOUND;
     if v_deptno = 3 then
        delete from emp where current of emp_cursor;
     end if;
  end loop;
  close emp_cursor;
end;

--使用OF子句在特定表上加上行共享锁
--如果游标子查询涉及到多张表,那么在默认情况下会在所有修改表行上加行共享锁。
--为了只在特定表上加行共享锁,需要在FOR UPDATE子句后带有OF子句
DECLARE
  CURSOR emp_cursor is 
     select ename,sal,dname,emp.deptno from emp,dept
     where emp.deptno = dept.deptno
     for update of emp.deptno;
  emp_record emp_cursor%ROWTYPE;
begin
  open emp_cursor;
  loop
     fetch emp_cursor into emp_record;
     exit when emp_cursor%NOTFOUND;
     if emp_record.deptno=1 then
        update emp set sal=sal+100 where current of emp_cursor;
     end if;
     dbms_output.put_line('雇员名:'||emp_record.ename||',工资:'||emp_record.sal||',部门名:'||emp_record.dname);
  end loop;
  close emp_cursor;
END;

--使用NOWAIT子句
--使用FOR UPDATE语句对被作用行加锁,如果其他会话已经在被作用行上加锁,那么在默认情况下当前会话会要一直等待对方释放锁
--通过在FOR UPDATE子句中指定NOWAIT语句,可以避免等待锁。
--当指定了NOWAIT子句之后,如果其他会话已经在被作用行加锁,那么当前会话会显示错误提示信息,并退出PL/SQL块
DECLARE
   CURSOR emp_cursor is 
      select ename,sal from emp for update nowait;
   v_ename emp.ename%TYPE;
   v_oldsal emp.sal%TYPE;
begin
   open emp_cursor;
   loop
      fetch emp_cursor into v_ename,v_oldsal;
      exit when emp_cursor%NOTFOUND;
      if v_oldsal<1000 then
         update emp set sal=sal+100 where current of emp_cursor;
      end if;
   end loop;
   close emp_cursor;
end;

select * from emp;

--游标FOR循环
--使用游标FOR循环
--以顺序显示EMP表的所有雇员为例,说明使用游标FOR循环的方法
DECLARE 
   CURSOR emp_cursor IS SELECT ename,sal from emp;
BEGIN
   for emp_record in emp_cursor loop
      dbms_output.put_line('第'||emp_cursor%ROWCOUNT||'个雇员:'||emp_record.ename);
   end loop;
END;

--在游标FOR循环中直接使用子查询
--如果在使用游标FOR循环时不需要使用任何游标属性,那么可以直接在游标FOR循环中使用子查询
--下面以显示EMP表的所有雇员名为例,说明在游标FOR循环中直接使用子查询的方法
BEGIN
   FOR emp_record in 
      (select ename,sal from emp) loop
      dbms_output.put_line(emp_record.ename);
   end LOOP;
END;

--使用游标变量
--在定义REF CURSOR类型时不指定RETURN子句
DECLARE
   TYPE emp_cursor_type is ref cursor;
   emp_cursor emp_cursor_type;
   emp_record emp%ROWTYPE;
begin
   open emp_cursor for select * from emp where deptno=1;
   loop
      fetch emp_cursor into emp_record;
      exit when emp_cursor%NOTFOUND;
      DBMS_OUTPUT.PUT_LINE('第'||emp_cursor%ROWCOUNT||'个雇员:'||emp_record.ename);
   end loop;
   close emp_cursor;
end;

--在定义REF CURSOR类型时指定RETURN子句
--如果在定义REF CURSOR类型时指定了RETURN子句,在打开游标时SELECT语句的返回结果必须与RETURN子句所指定的记录类型相匹配
--下面以顺序地显示部门20的所有雇员名称为例,说明使用游标变量(包含RETURN子句)的方法
DECLARE
  TYPE emp_record_type is record(
     name VARCHAR2(10),salary NUMBER(6,2));
  type emp_cursor_type is ref cursor
     return emp_record_type;
  emp_cursor emp_cursor_type;
  emp_record emp_record_type;
BEGIN
  open emp_cursor for select ename,sal from emp where deptno=2;
  loop
    fetch emp_cursor into emp_record;
    exit when emp_cursor%NOTFOUND;
    dbms_output.put_line('第'||emp_cursor%ROWCOUNT||'个雇员:'||emp_record.name||',工资:'||emp_record.salary);
  end loop;
  close emp_cursor;
END;

--使用CURSOR表达式
--CURSOR表达式用于返回嵌套游标
--通过使用CURSOR表达式,开发人员可以在PL/SQL块中处理更加复杂的基于多张表的关联数据
--为了在PL/SQL块中取得嵌套游标的数据,需要使用嵌套循环
--下面以显示部门名、雇员名和工资为例,说明在PL/SQL块中使用CURSOR表达式的方法
DECLARE
   TYPE refcursor is ref cursor;
   cursor dept_cursor(no number) is 
      select a.dname,cursor(select ename,sal from emp where deptno=a.deptno) from dept a where a.deptno=no;
   empcur refcursor;
   v_dname dept.dname%TYPE;
   v_ename emp.ename%TYPE;
   v_sal emp.sal%TYPE;
begin
   open dept_cursor(&no);
   loop 
     fetch dept_cursor into v_dname,empcur;
     exit when dept_cursor%NOTFOUND;
     dbms_output.put_line('部门名:'||v_dname);
     loop
       fetch empcur into v_ename,v_sal;
       exit when empcur%NOTFOUND;
       DBMS_OUTPUT.put_line('雇员名:'||v_ename||',工资:'||v_sal);
     end loop;
   end loop;
   close dept_cursor;
end;

select * from emp;
select * from dept;

 

分享到:
评论

相关推荐

    精通Oracle10编程SQL(1-3)PLSQL基础

    "精通Oracle10编程SQL(9)使用游标.sql"讲解了游标的概念和应用,游标是数据库编程中的重要工具,用于逐行处理查询结果,尤其在循环处理或动态操作数据时非常有用。 "精通Oracle10编程SQL(11)开发子程序.sql"和"精通...

    精通Oracle 10g SQL和PL SQL.zip

    本资源“精通Oracle 10g SQL和PL SQL.zip”提供了全面的学习指南,帮助用户从基础到高级进阶,掌握这两个重要组件的精髓。 SQL(Structured Query Language)是用于管理关系数据库的标准语言,它允许用户创建、查询...

    《精通Oracle10编程》 PDF

    《精通Oracle10编程》是一本专为数据库管理员和开发者设计的专业书籍,旨在深入解析Oracle 10g数据库系统的各种核心技术和高级特性。Oracle 10g是Oracle公司推出的一个重要版本,它在性能、可扩展性和管理性方面都有...

    Oracle 11g SQL和PL SQL从入门到精通 pdf格式电子书 下载(一)

     本书是专门为oracle应用开发人员提供的sql和pl/sql编程指南。通过学习本书,读者不仅可以掌握oracle常用工具oracle universal installer、net comfiguration assistant、sql developer、sql*plus的作用及使用方法...

    精通Oracle PLSQL编程

    通过阅读《精通Oracle PLSQL编程》这本书,你将有机会掌握这些核心概念,并逐步成为一个熟练的Oracle数据库开发者。书中的实例和练习将帮助你更好地理解和应用这些技术,为你的职业生涯打下坚实的基础。

    精通Oracle10g SQL/PL编程.PDF

    《精通Oracle10g SQL/PL编程》是一本专为数据库开发者和管理员设计的专业书籍,旨在深入探讨Oracle10g数据库管理系统中的SQL和PL/SQL编程技术。这本书以通俗易懂的方式,为初学者提供了全面的学习路径,同时也为有...

    《精通Oracle PL/SQL》源码

    《精通Oracle PL/SQL》这本书深入探讨了这个语言的各个方面,旨在帮助读者掌握其精髓并提升在数据库开发中的效率。书中提供的源码示例是学习和理解PL/SQL语法、功能以及最佳实践的重要资源。 在"2174_...

    精通Oracle10编程.pdf

    通过以上几个方面的介绍,我们可以看到“精通Oracle10编程.pdf”这一资料中涉及的知识点主要包括:Oracle 10g的基础介绍、嵌套表类型的应用、引用变量的声明、游标的使用以及变量命名规则等方面。这些内容对于深入...

    精通Oracle10编程

    本书"精通Oracle10编程"旨在深入解析Oracle 10g的PL/SQL编程语言,帮助读者掌握这一强大工具的核心技术和最佳实践。PL/SQL(Procedural Language/Structured Query Language)是Oracle特有的数据库编程语言,将SQL的...

    精通oracle10编程 教程 +pl/sql pdf

    本教程的"精通Oracle10编程"部分,将深入讲解如何使用PL/SQL进行数据库交互,包括变量声明、流程控制、异常处理和游标等基本概念。 在PL/SQL编程中,了解SQL DML语句(INSERT、UPDATE、DELETE)是基础,它们用于...

    精通Oracle10编程(从入门到精通).rar

    本书“精通Oracle10编程”旨在帮助初学者掌握Oracle数据库的基本操作和高级编程技巧,实现从入门到精通的跨越。 Oracle10g是Oracle数据库的一个重要版本,它引入了许多新特性和改进,提升了性能、可用性和可管理性...

    精通Oracle10g PLSQL编程.rar

    在"精通Oracle10g PLSQL编程"的资料中,你将深入学习到如何有效地使用这一语言进行数据库管理和应用开发。 1. **PLSQL基础** - **变量和数据类型**:理解PLSQL中的基本数据类型,如NUMBER、VARCHAR2、DATE等,并...

    精通ORACLE 10G SQL和PL_SQL

    本资源"精通ORACLE 10G SQL和PL_SQL"旨在帮助用户深入理解并熟练掌握这两门语言在实际应用中的技巧。 SQL,全称为结构化查询语言,是用于管理关系数据库的标准语言。在Oracle 10g中,SQL主要分为以下几个部分: 1....

    精通Oracle10g PL_SQL编

    本教程《精通Oracle10g PL_SQL编程》旨在帮助学习者深入理解并熟练掌握Oracle 10g中的PL/SQL编程技术。 1. PL/SQL基础 - PL/SQL的结构:包括声明部分、执行部分和异常处理部分。 - 变量和常量:定义、声明及使用...

    ORACLE PL/SQL从入门到精通

    ORACLE PL/SQL是从入门到精通的专业知识,涵盖了数据库开发与管理的多个方面,包括触发器、过程、函数、软件包、异常处理、游标、循环、分支、变量使用、数据库安装等关键知识点。 触发器是数据库中用来保证数据...

    精通Oracle 10g PL/SQL编程

    《精通Oracle 10g PL/SQL编程》是一本针对Oracle数据库系统中PL/SQL编程语言的深度解析书籍。Oracle 10g是Oracle数据库的一个重要版本,它提供了丰富的功能和改进,使得PL/SQL这一数据库编程语言在性能、可维护性和...

    Oracle 11g SQL和PL SQL从入门到精通 pdf格式电子书 下载(二)

     本书是专门为oracle应用开发人员提供的sql和pl/sql编程指南。通过学习本书,读者不仅可以掌握oracle常用工具oracle universal installer、net comfiguration assistant、sql developer、sql*plus的作用及使用方法...

    《精通Oracle 10g Pro*C/C++编程》源代码与学习笔记

    《精通Oracle 10g Pro*C/C++编程》是一本专为数据库开发人员设计的教程,作者王海亮和张立民通过这本书深入探讨了如何使用C或C++语言与Oracle 10g数据库进行高效交互。源代码与学习笔记的提供,为读者提供了实践操作...

    oracle pl/sql从入门到精通 配套源代码

    Oracle PL/SQL是一种强大的编程...每个示例都是一次学习的机会,通过分析和运行这些代码,你可以逐步精通Oracle数据库的编程。记住,理论知识固然重要,但实践是检验真理的唯一标准,因此动手实践是掌握PL/SQL的关键。

Global site tag (gtag.js) - Google Analytics