一、游标  

  游标用来处理从数据库中检索的多行记录(使用SELECT语句)。利用游标,程序可以逐个地处理和遍历一次检索返回的整个记录集。

为了处理SQL语句,Oracle将在内存中分配一个区域,这就是上下文区。这个区包含了已经处理完的行数、指向被分析语句的指针,整个区是查询语句返回的数据行集。游标就是指向上下文区句柄或指针。

二、游标的分类:

  1、静态游标:静态游标是在编译时知道其SELECT语句的游标。静态游标又分为两种类型,隐式游标和显示游标。

  2、动态游标:用户为游标使用的查询直到运行的时候才能确定,可以使用REF游标和游标变量满足这个要求。为了使用引用游标,必须声明游标变量。有两种类型的REF游标:强类型REF游标和弱类型REF游标。

三、显示游标的用法:

  显示游标被用于处理返回多行数据的SELECT 语句,游标名通过CURSOR….IS 语句显示地赋给SELECT 语句。

(一)使用步骤;

1)声明游标:CURSOR cursor_name IS select_statement

2)为查询打开游标:OPEN cursor_name

3)取得结果放入PL/SQL变量中;

FETCH cursor_name INTO list_of_variables;

 FETCH cursor_name INTO PL/SQL_record;

4)关闭游标。CLOSE cursor_name

  注意:在声明游标时,select_statement不能包含INTO子句。当使用显示游标时,INTO子句是FETCH语句的一部分。

  例:显示雇员的名称和薪水

  1. --使用LOOP遍历游标
  2. DECLARE
  3. v_name emp.ename%TYPE;
  4. v_sal emp.sal%TYPE;
  5. CURSOR cus_emp IS
  6. SELECT ename,sal FROM emp; --声明游标
  7. BEGIN
  8. OPEN cus_emp; --打开游标
  9. LOOP
  10. FETCH cus_emp INTO v_name,v_sal; --提取游标
  11. EXIT WHEN cus_emp%NOTFOUND;
  12. dbms_output.put_line('第'||cus_emp%ROWCOUNT||'个用户: name:'||v_name||' sal:'||v_sal);
  13. END LOOP;
  14. CLOSE cus_emp; --关闭游标
  15. END;

  显示游标的属性:

  %FOUND:只有在DML语句影响一行或者多行是,则返回TRUE;

  %NOTFOUND:没有影响任何行,则返回TRUE。

  %ROWCOUNT:返回DML语句影响的行数,没有影响则返回0;

  %ISOPEN:返回游标是否打开,在执行SQL之后,Oracle自动关闭SQL游标,所以隐式游标的%isopen属性始终未false;

  另一种方式:

  1. --使用for来简化游标遍历
  2. DECLARE
  3. CURSOR cus_emp IS
  4. SELECT ename,sal FROM emp;
  5. BEGIN
  6. FOR record_emp IN cus_emp
  7. LOOP
  8. dbms_output.put_line('第'||cus_emp%ROWCOUNT||'个用户: name:'||record_emp.ename||' sal:'||record_emp.sal);
  9. END LOOP;
  10. END;

  record_emp是plsql声明的的记录变量,此变量的属性为声明为%ROWTYPE类型,作用域在FOR循环之内,即在FOR循环外就不能访问了。

  循环游标的特性:
  (1)从游标中提取了所有记录之后自动终止。
  (2)提取和处理游标中的每一条记录。
  (3)如果在提取记录之后%NOTFOUND属性返回TRUE,则终止循环。如果未返回任何行,则不进入循环。

游标案例:  

  1. --给员工加薪,按员工入职时间进行加薪,每年加1001000封顶
  2. DECLARE
  3. v_date emp.hiredate%TYPE;
  4. v_empno emp.empno%TYPE;
  5. v_money NUMBER;
  6. CURSOR cur_emp IS
  7. SELECT empno,hiredate FROM emp;
  8. BEGIN
  9. OPEN cur_emp;
  10. LOOP
  11. FETCH cur_emp INTO v_empno,v_date;
  12. EXIT WHEN cur_emp%NOTFOUND;
  13. v_money := 100*(1990-to_char(v_date,'yyyy'));
  14. IF v_money<1000 THEN
  15. UPDATE emp SET sal=sal+v_money WHERE empno=v_empno;
  16. ELSE
  17. UPDATE emp SET sal=sal+1000 WHERE empno=v_empno;
  18. END IF;
  19. END LOOP;
  20. END;

 带参数的游标

  语法:

  CURSOR cursor_name[(parameter[,parameter],...)] IS select_statement;

  定义参数的语法如下:Parameter_name [IN] data_type[{:=|DEFAULT} value]

  1. 例:接收用户输入的部门编号,用for循环和游标,打印出此部门的所有雇员的所有信息(使用循环游标)
  1. DECLARE
  2. CURSOR C_DEPT(P_DEPTNO NUMBER) IS
  3. SELECT * FROM EMP WHERE EMP.DEPTNO = P_DEPTNO;
  4. R_EMP EMP%ROWTYPE;
  5. BEGIN
  6. FOR R_EMP IN C_DEPT(30) LOOP
  7. DBMS_OUTPUT.PUT_LINE('员工号:' || R_EMP.EMPNO || '员工名:' || R_EMP.ENAME ||
  8. '工资:' || R_EMP.SAL);
  9. END LOOP;
  10. END;
  1.  

四、隐式游标:

  所有的隐式游标都被假设为只返回一条记录。
  使用隐式游标时,用户无需进行声明、打开及关闭。PL/SQL隐含地打开、处理,然后关掉游标。多条sql语句 隐式游标SQL永远指的是最后一条sql语句的结果,主要使用在update 和 delete语句上。

  隐式游标的四个属性:

属性 说明
 SQL%rowcount  影响的记录的行数整数(用来判断插入,更新修改是否成功,必须在comit之前,否则提交后结果为0.)
 SQL%found  影响到了记录 true()
 SQL%notfound  没有影响到记录 true
 SQL%isopen  是否打开 布尔值 永远是false

例如:

  1. DECLARE
  2. row_emp emp%ROWTYPE;
  3. BEGIN
  4. SELECT ename,sal INTO row_emp.ename,row_emp.sal
  5. FROM emp WHERE emp.empno = 7369;
  6. --判断是否查到数据
  7. if(SQL%ROWCOUNT=1) THEN
  8. dbms_output.put_line('找到了');
  9. END IF;
  10. --另一种方式判断
  11. IF(SQL%Found) THEN
  12. dbms_output.put_line('找到了');
  13. END IF;
  14.  
  15. dbms_output.put_line('ename:'||row_emp.ename||' sal:'||row_emp.sal);
  16. END;

上述游标自动打开,并把相关值赋给对应变量,然后关闭。执行完后,PL/SQL变量rowemp.ename,rowemp.sal中已经有了值。

五:动态游标

  静态游标是在声明就已经确定查询语句,如果用户需要在运行时动态决定游标执行的查询,就需要使用动态游标(REF游标)。

  动态游标分为两类:强类型游标和弱类型游标。

  动态游标使用步骤:

  1、声明动态游标类型;

  2、打开游标,指定游标查询;

  3、提取游标。

  4、关闭游标。

  例:

  强类型游标,使用return声明的游标为强类型游标。在对游标进行绑定查询只能绑定游标返回的类型rowtype。

  1. --强类型的动态游标,查询emp表中的数据
  2. DECLARE
  3. TYPE ref_cur IS REF CURSOR --声明游标类型
  4. RETURN emp%ROWTYPE; --带返回值的为强类型动态游标
  5. refcur_emp ref_cur; --游标类型对象
  6. v_emp emp%ROWTYPE;
  7. BEGIN
  8. OPEN refcur_emp FOR --将游标绑定到一个查询语句,因为声明的是强类型,所以只能绑定emp;
  9. SELECT * FROM emp;
  10. LOOP
  11. FETCH refcur_emp INTO v_emp; --提取游标内容
  12. EXIT WHEN refcur_emp%NOTFOUND;
  13. dbms_output.put_line(refcur_emp%Rowcount||'、name:'||v_emp.ename||' sal:'||v_emp.sal);
  14. END LOOP;
  15. CLOSE refcur_emp;
  16. END;

  

  弱类型游标:可以用来绑定多个查询结果。

  例:

  1. --弱类型游标
  2. DECLARE
  3. TYPE refcur IS REF CURSOR; --未定义返回类型为弱类型游标
  4. rc refcur;
  5. v_name emp.ename%TYPE;
  6. v_deptname dept.dname%TYPE;
  7. BEGIN
  8. OPEN rc FOR SELECT ename,dname FROM emp e,dept d WHERE e.deptno = d.deptno; --绑定查询
  9. LOOP
  10. FETCH rc INTO v_name,v_deptname;
  11. EXIT WHEN rc%NOTFOUND;
  12. dbms_output.put_line('name:'||v_name||' deptname:'||v_deptname);
  13. END LOOP;
  14. CLOSE rc;
  15. END;

  例:

  1. --根据输入的内容绑定游标
  2. DECLARE
  3. TYPE refcur IS REF CURSOR;
  4. rc refcur;
  5. v_tablename VARCHAR2(10) := '&tab';
  6. v_id NUMBER;
  7. v_name VARCHAR2(20);
  8. BEGIN
  9. IF(v_tablename = 'e') THEN
  10. OPEN rc FOR
  11. SELECT e.empno,e.ename INTO v_id,v_name FROM emp e;
  12. dbms_output.put_line('=========员工信息=============');
  13. Elsif(v_tablename = 'd') THEN
  14. OPEN rc FOR
  15. SELECT d.deptno,d.dname INTO v_id,v_name FROM dept d;
  16. dbms_output.put_line('=========部门信息=============');
  17. ELSE
  18. dbms_output.put_line('输入错误,请输入e或者d!');
  19. RETURN;
  20. END IF;
  21.  
  22. LOOP
  23. FETCH rc INTO v_id,v_name;
  24. dbms_output.put_line('#'||rc%Rowcount||' id:'||v_id||' name:'||v_name);
  25. EXIT WHEN rc%NOTFOUND;
  26. END LOOP;
  27. END;

六、动态游标和静态游标的区别:  

  1、静态游标是静态定义,REF 游标是动态关联;

  2、使用REF 游标需REF 游标变量。

  3、REF 游标能做为参数进行传递,而静态游标是不可能的。

Oracle基础 游标的更多相关文章

  1. Oracle 基础 游标

    一:游标的基本原理 游标用来处理从数据库中检索的多行记录(使用SELECT语句).利用游标,程序可以逐个地处理和遍历一次检索返回的整个记录集. 为了处理SQL语句,Oracle将在内存中分配一个区域, ...

  2. oracle基础教程(8)oracle修改字符集

    oracle基础教程(8)oracle修改字符集 1.用dba连接数据库 -->sqlplus / as sysdba 2.查看字符集 -->SELECT parameter, value ...

  3. 设置ORACLE数据库游标大小

    先用超级管理员(sys)登陆服务器: sqlplus "sys/***@orcl as sysdba" 连接到:Oracle 查看ORACLE最大游标数: SQL> show ...

  4. Oracle使用游标为所有用户表添加主键语句

    应用场合:数据表新增自增一主键能加快数据表的访问速度,而且是整形的索引速度最快.本程序适合在导入Oracle数据库时删除不存在主键的情况下运行. 代码说明:所有的表主键字段名都设置为ID,如果已存在I ...

  5. Oracle使用游标查询指定数据表的所有字段名称组合而成的字符串

    应用场合:参考网上查询数据表的所有字段名代码,使用游标生成指定单个表的所有字段名跟逗号组成的用于select  逗号隔开的字段名列表 from字符串等场合. 查询结果输出如下: 当前数据表TB_UD_ ...

  6. Oracle使用游标删除所有用户数据表中的所有记录脚本

    应用场景:因为数据库中的数据涉及机密信息,希望一次性能删除掉所有数据,只保留数据表结构,供新项目开发程序用 测试结果:经查询已删除所有数据 存在问题:数据表如果存在外键的话下面脚本可能执行不成功,请自 ...

  7. 图说Oracle基础知识(一)

    本文主要对Oralce数据库操作的基础知识进行一下梳理,以便进行归纳总结.适用于未使用过Oracle数据库的读者,或需要学习Oracle数据库方面的基础知识.如有不足之处,还请指正. 关于SQL介绍的 ...

  8. (2.14)Mysql之SQL基础——游标

    (2.14)Mysql之SQL基础——游标 关键词:Mysql游标 -- (1)定义游标 declare cur_name cursor for select * from table_name wh ...

  9. oracle基础教程oracle客户端详解

    oracle基础教程oracle客户端工具详解 参考网址:http://www.oraclejsq.com/article/010100114.html 该教程介绍了oracle自带客户端sqlplu ...

随机推荐

  1. IP地址转换成Long型数字的算法

    在应用程序开发中,涉及到IP地址的存储,大部分开发人员都将其存为String(或文本类型).能否将固定格式为m.n.x.y的IP地址转换成 Long型的数字呢?答案是肯定的.在数据库层面,可以直接将结 ...

  2. 文件拷贝以及base64

    File inFile = new File("d:" + File.separator + "test.jpg"); File outFile = new F ...

  3. Objc基础学习记录3

    在学习Objective-c中, 数组 1.NSArray, 这是一个不可变的数组,不能修改和删除其中的对象,可以存储任意objective的对象指针. 不能存储int,char类型的,,需要转换为需 ...

  4. Unity3d:The requested item has been unloaded

    问题描述:System.Xml类库下实例化的对象所有枚举类的值都显示如标题错误解决方案1:查看所在类是否:MonoBehaviour,如果没继承,添加即可.<ignore_js_op> 

  5. nginx 配置虚拟主机(支持php)

    配置步骤: 1.在nginx安装目录下,找到nginx.conf所在文件夹,新建vhost文件夹 2.在nginx.conf http{} 末端加入 include vhost/*.conf; 3.进 ...

  6. AS与JS相互通信(Flex中调用js函数)

    转载自http://www.blogjava.net/Alpha/archive/2009/06/27/284373.html Flex中As调用Js的方法是:     1.导入包 (import f ...

  7. wpa_supplicant 连接成功后,如何配置wlan0与br0 协调上网

    wlan0 地址,路由配置完成后,加入两条iptables 规则. #iptables -A FORWARD -i wlan0 -o br0 -s -m state --state NEW -j AC ...

  8. C# 反射类型转换

    /// <summary> /// 泛型类型转换 /// </summary> /// <typeparam name="T">要转换的基础类型 ...

  9. 为网页设计师和开发者准备的20个很棒的JavaScript资源

    JavaScript是一门应用广泛的计算机编程语言,一般具应用在Web浏览器中,大多用于客户端脚本以实现用户与服务器的交互.在游戏开发.移动应用.一些大型的服务器应用等开发进程中它在服务器端的应用也很 ...

  10. cdoj 25 点球大战(penalty) 模拟题

    点球大战(penalty) Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/2 ...