一、游标概述:

游标(cursor)是数据库系统在内存中开设的一个数据缓冲区,存放SQL语句的执行结果。

每个游标都有一个名字,用户可以用SQL语句逐一从游标中获取记录,并赋给变量做进一步处理。

作用:用于定位结果集的行 和 遍历结果集。

二、游标分类:

显式游标:在前述程序中用到的SELECT...INTO...查询语句,一次只能从数据库中提取一行数据,对于这种形式的查询和DML操作,系统都会使用一个隐式游标

隐式游标:但是如果要提取多行数据,就要由程序员定义一个显式游标,并通过与游标有关的语句进行处理。显式游标对应一个返回结果为多行多列的SELECT语句。

三:显示游标:

处理显示游标需要的四个步骤:

定义游标:就是定义一个游标的名称,以及与其对应的SELECT语句,形式如下

CURSOR 游标名称 IS select_statement

打开游标 :open 游标变量(不能重复打开游标)

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

提取数据 :fetch 游标变量 into 变量1,变量2,……

提取操作必须在打开游标之后进行。

关闭游标:close 游标变量

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

--查询输出所有员工的编号,姓名,工资:(当执行fetch时提取数据指针下移一行)

DECLARE

v_empid employees.employee_id%TYPE;

v_name employees.last_name%TYPE;

v_salary employees.salary%TYPE;

CURSOR emp_cursor IS

SELECT employee_id,last_name,salary

FROM employees

WHERE department_id=90;

BEGIN

OPEN emp_cursor;

FETCH emp_cursor INTO v_empid,v_name,v_salary;--默认指向第一行

FETCH emp_cursor INTO v_empid,v_name,v_salary;

FETCH emp_cursor INTO v_empid,v_name,v_salary;

dbms_output.put_line(‘编号:‘ || v_empid);

dbms_output.put_line(‘姓名:‘ || v_name);

dbms_output.put_line(‘工资:‘ || v_salary);

CLOSE emp_cursor;

END;

四:游标的四个属性

游标变量%found:当最近一次读记录时成功返回,则值为TRUE

游标变量%notfound:同上,求反

游标变量%isopen:判断游标是否已经打开

游标变量%rowcount:返回已从游标中读取的记录数

--查询输出所有员工的编号,姓名,工资

loop循环

DECLARE

v_empid employees.employee_id%TYPE;

v_name employees.last_name%TYPE;

v_salary employees.salary%TYPE;

CURSOR emp_cursor IS

SELECT employee_id,last_name,salary

FROM employees;

BEGIN

OPEN emp_cursor;

LOOP

FETCH emp_cursor INTO v_empid,v_name,v_salary;

EXIT WHEN emp_cursor%NOTFOUND;--读取最后一次失败后跳出循环

dbms_output.put_line(‘编号:‘ || v_empid);

dbms_output.put_line(‘姓名:‘ || v_name);

dbms_output.put_line(‘工资:‘ || v_salary);

dbms_output.put_line(‘--------------------‘);

END LOOP;

CLOSE emp_cursor;

END;

while 循环

DECLARE

v_empid employees.employee_id%TYPE;

v_name employees.last_name%TYPE;

v_salary employees.salary%TYPE;

CURSOR emp_cursor IS

SELECT employee_id,last_name,salary

FROM employees;

BEGIN

OPEN emp_cursor;

FETCH emp_cursor INTO v_empid,v_name,v_salary;

WHILE emp_cursor%FOUND LOOP

dbms_output.put_line(‘编号:‘ || v_empid);

dbms_output.put_line(‘姓名:‘ || v_name);

dbms_output.put_line(‘工资:‘ || v_salary);

dbms_output.put_line(‘--------------------‘);

FETCH emp_cursor INTO v_empid,v_name,v_salary;

END LOOP;

CLOSE emp_cursor;

END;

--查询输出所有员工的编号,姓名,工资(PLSQL表类型)

DECLARE

TYPE emp_table_type IS TABLE OF employees%ROWTYPE

INDEX BY BINARY_INTEGER;

e emp_table_type;

CURSOR emp_cursor IS

SELECT *

FROM employees;

BEGIN

OPEN emp_cursor;

FETCH emp_cursor BULK COLLECT INTO e;

FOR i IN 1..e.COUNT LOOP

dbms_output.put_line(‘编号:‘ || e(i).employee_id);

dbms_output.put_line(‘姓名:‘ || e(i).last_name);

dbms_output.put_line(‘工资:‘ || e(i).salary);

dbms_output.put_line(‘--------------------‘);

END LOOP;

CLOSE emp_cursor;

END;

--查询输出所有员工的编号,姓名,工资(通过limit控制提取的数据量)每次提取6条数据

DECLARE

TYPE emp_table_type IS TABLE OF employees%ROWTYPE

INDEX BY BINARY_INTEGER;

e emp_table_type;

v_count NUMBER := 1;

CURSOR emp_cursor IS

SELECT *

FROM employees;

BEGIN

OPEN emp_cursor;

LOOP

dbms_output.put_line(‘第‘ || v_count || ‘次FETCH‘);

FETCH emp_cursor BULK COLLECT INTO e LIMIT 6;

FOR i IN 1..e.COUNT LOOP

dbms_output.put_line(‘编号:‘ || e(i).employee_id);

dbms_output.put_line(‘姓名:‘ || e(i).last_name);

dbms_output.put_line(‘工资:‘ || e(i).salary);

dbms_output.put_line(‘--------------------‘);

END LOOP;

EXIT WHEN emp_cursor%NOTFOUND;

v_count := v_count + 1;

END LOOP;

CLOSE emp_cursor;

END;

--查询输出某个部门的员工的编号,姓名,工资(参数化游标)

DECLARE

v_empid employees.employee_id%TYPE;

v_name employees.last_name%TYPE;

v_salary employees.salary%TYPE;

CURSOR emp_cursor(p_deptid employees.department_id%TYPE) IS

SELECT employee_id,last_name,salary

FROM employees

WHERE department_id=p_deptid;

BEGIN

OPEN emp_cursor(50);

LOOP

FETCH emp_cursor INTO v_empid,v_name,v_salary;

EXIT WHEN emp_cursor%NOTFOUND;

dbms_output.put_line(‘编号:‘ || v_empid || ‘,姓名:‘ || v_name || ‘,工资:‘ || v_salary);

END LOOP;

CLOSE emp_cursor;

dbms_output.put_line(‘----------------------‘);

OPEN emp_cursor(90);

LOOP

FETCH emp_cursor INTO v_empid,v_name,v_salary;

EXIT WHEN emp_cursor%NOTFOUND;

dbms_output.put_line(‘编号:‘ || v_empid || ‘,姓名:‘ || v_name || ‘,工资:‘ || v_salary);

END LOOP;

CLOSE emp_cursor;

END;

五:游标for循环:

PL/SQL中提供了游标for循环语句,可以自动的执行游标的open,fetch,close语句和循环语句的功能,当进入循环时,游标for循环语句自动打开游标,并提取第一行数据,提取

提取完成后自动进入下一个提取,提取完成后自动关闭游标:

--查询输出所有员工的编号,姓名,工资

DECLARE

CURSOR emp_cursor IS

SELECT *

FROM employees;

BEGIN

FOR e IN emp_cursor LOOP

dbms_output.put_line(e.employee_id||‘,‘||e.last_name||‘,‘||e.salary);

END LOOP;

END;

--查询输出所有员工的编号,姓名,工资(带参数)

DECLARE

CURSOR emp_cursor(p_deptid employees.department_id%TYPE) IS

SELECT *

FROM employees

WHERE department_id=p_deptid;

BEGIN

FOR e IN emp_cursor(90) LOOP

dbms_output.put_line(e.employee_id||‘,‘||e.last_name||‘,‘||e.salary);

END LOOP;

END;

--查询输出所有员工的编号,姓名,工资(最精简写法)

DECLARE

BEGIN

FOR e IN (SELECT * FROM employees) LOOP

dbms_output.put_line(e.employee_id||‘,‘||e.last_name||‘,‘||e.salary);

END LOOP;

END;

--输出每个部门的部门编号,部门名称以及这个部门的下属员工的编号,姓名,工资

/*

10 nec

100,tom,2400

101,jack,17000

20 ge

102,rose,2600

xxx,xxx,xxx

xxx,xxx,xxx

40 hsw

xxx,xxx,xxx

*/

DECLARE

CURSOR dept_cursor IS

SELECT * FROM departments;

CURSOR emp_cursor(p_deptid NUMBER) IS

SELECT * FROM employees

WHERE department_id=p_deptid;

BEGIN

FOR d IN dept_cursor LOOP

dbms_output.put_line(d.department_id || ‘ ‘ || d.department_name);

FOR e IN emp_cursor(d.department_id) LOOP

dbms_output.put_line(‘ ‘ || e.employee_id || ‘,‘ || e.last_name || ‘,‘ || e.salary);

END LOOP;

END LOOP;

END;

/*

隐式游标:固定名称SQL

游标四个属性:

SQL%FOUND:如果操作有影响的行,就为TRUE,否则为FALSE

SQL%NOTFOUND:求反

SQL%ISOPEN:在隐式游标中,取值永远为FALSE

SQL%ROWCOUNT:操作影响的行数

必须在事务结束之前读取游标属性,只能读取最近的一次DML操作的游标状态

*/

--用户输入一个任意的部门编号,更新这个部门的员工的工资

--如果有员工被更新,输出“更新成功,有XX个员工被更新”

--如果没有任何员工被更新,输出“这个部门不存在,没有任何员工被更新”

DECLARE

v_deptid NUMBER := &input;

BEGIN

UPDATE employees

SET salary = salary + 1

WHERE department_id = v_deptid;

IF SQL%FOUND THEN

dbms_output.put_line(‘更新成功,有‘ || SQL%ROWCOUNT || ‘个员工被更新‘);

ELSE

dbms_output.put_line(‘这个部门不存在,没有任何员工被更新‘);

END IF;

COMMIT;

END;

--通过游标去更新员工的工资,如果工资低于5000块,则把工资改为5000

DECLARE

CURSOR emp_cursor IS

SELECT * FROM new_emp FOR UPDATE;

BEGIN

FOR e IN emp_cursor LOOP

IF e.salary<5000 THEN

UPDATE new_emp SET salary=5000 WHERE CURRENT OF emp_cursor;

END IF;

END LOOP;

END;

--通过游标删除工资=5000的员工

DECLARE

CURSOR emp_cursor IS

SELECT * FROM new_emp FOR UPDATE;

BEGIN

FOR e IN emp_cursor LOOP

IF e.salary=5000 THEN

DELETE FROM new_emp WHERE CURRENT OF emp_cursor;

END IF;

END LOOP;

END;

--游标变量(动态游标)

--用户输入一个字母,输入E,输出所有员工姓名,如果输入D,输出所有部门的名称

DECLARE

v_cmd CHAR(1) := ‘&input‘;

v_name VARCHAR2(50);

--声明自定义的游标变量类型

--TYPE c_type IS REF CURSOR;

--声明游标变量

--c c_type;

c SYS_REFCURSOR;--代替TYPE c_type IS REF CURSOR

BEGIN

IF v_cmd=‘E‘ THEN

dbms_output.put_line(‘员工姓名‘);

OPEN c FOR SELECT last_name FROM employees;

ELSIF v_cmd=‘D‘ THEN

dbms_output.put_line(‘部门名称‘);

OPEN c FOR SELECT department_name FROM departments;

ELSE

dbms_output.put_line(‘输入无效‘);

RETURN;

END IF;

LOOP

FETCH c INTO v_name;

EXIT WHEN c%NOTFOUND;

dbms_output.put_line(v_name);

END LOOP;

CLOSE c;

END;

Oracle游标 CURSOR实例详解

标签:工资   lan   art   dml   获取   作者   fetch   https   type

本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉 本文系统来源:https://www.cnblogs.com/520gqk/p/9862859.html

oracle 记录给游标,Oracle游标 CURSOR实例详解相关推荐

  1. oracle触发器函数,oracle 存储过程、函数和触发器用法实例详解

    本文实例讲述了oracle 存储过程.函数和触发器用法.分享给大家供大家参考,具体如下: 一.存储过程和存储函数 指存储在数据库中供所有用户程序调用的子程序叫存储过程.存储函数. 创建存储过程 用CR ...

  2. oracle rank 语法_Oracle排名函数(Rank)实例详解

    -- 已知:两种排名方式 ( 分区和不分区 ): 使用和不使用 partition -- 两种计算方式 ( 连续 , 不连续 ), 对应函数: dense_rank,rank ·查询原始数据:学号 , ...

  3. oracle几种例外,Oracle例外用法实例详解

    本文实例讲述了Oracle例外用法.分享给大家供大家参考,具体如下: 一.例外分类 oracle将例外分为预定义例外.非预定义例外和自定义例外三种. 1).预定义例外用于处理常见的oracle错误. ...

  4. Oracle排名函数(Rank)实例详解

    这篇文章主要介绍了Oracle排名函数(Rank)实例详解,需要的朋友可以参考下 --已知:两种排名方式(分区和不分区):使用和不使用partition --两种计算方式(连续,不连续),对应函数:d ...

  5. oracle大对象实例_Oracle解析复杂json的方法实例详解

    问题背景: 当前在Oracle数据库(11G之前的版本)解析json没有可以直接使用的系统方法,网上流传的PLSQL脚本大多也只可以解析结构较单一的json串,对于结构复杂的json串还无法解析.如此 ...

  6. java 获取oracle表结构_Java导出oracle表结构实例详解

    Java导出oracle表结构实例详解 发布于 2020-7-20| 复制链接 摘记:  Java导出oracle表结构实例详解最近用到的,因为plsql是收费的,不让用,找了很多方法终于发现了这个. ...

  7. oracle out参数查询,Oracle的out参数实例详解

    Oracle的out参数实例详解 一 概念 1.一般来讲,存储过程和存储函数的区别在于存储函数可以有一个返回值:而存储过程没有返回值. 2.过程和函数都可以通过out指定一个或多个输出行.我们可以利用 ...

  8. oracle中表空间实例,oracle的表空间实例详解

    oracle 的表空间实例详解 查询表空间 SELECT UPPER(F.TABLESPACE_NAME) "表空间名", D.TOT_GROOTTE_MB "表空间大小 ...

  9. oracle身份证的正则表达式,Oracle 正则表达式实例详解

    Oracle 正则表达式实例详解 FORM开发中的按行拆分需求:拆分后的行要有规律,并按前后层次排序 需求分析如下: 现有行: 2 , 2.1 , 2.2 , 2.3 3 2.1.1,2.1.2,2. ...

最新文章

  1. 使用SSH框架实现用户登录验证
  2. Day 18: BoilerPipe —— Java开发者的文章提取工具
  3. Executors框架——5种常用的线程池介绍及区别
  4. 轻量集群管理工具PSSH
  5. Android 自定义属性时TypedArray的使用
  6. 你觉得sql有多难?
  7. 2 创建型模式之 - 工厂模式
  8. java版本号分段比较_java比较版本号大小
  9. web操作日志丢失_分享:有赞百亿级日志系统架构设计
  10. 2022低压电工上岗证题目及答案
  11. SpringBoot开发的java后台管理系统
  12. HBase Shell 命令私藏
  13. 学计算机考研和就业前景,2016考研:解析研究生就业前景
  14. [绍棠] iOS开发- 文件共享(利用iTunes导入文件, 并且显示已有文件) 以及 iOS App与iTunes文件传输的方法和对iOS App文件结构的说明
  15. github(desktop)使用教程(三) 【保姆级】{desktop tutorial repository,创建分支,编辑文件,保存修改,commit,publish to github}
  16. 一文看懂大数据矩阵运算利器-Spark Distributed Matrix
  17. 【软考】【计算机网络】OSI/RM模型及相应硬件
  18. “偷梁换柱”的库打桩机制
  19. Try Catch block
  20. npm安装私有指定路径的依赖包

热门文章

  1. 【进阶版】机器学习之模型性能度量及比较检验和偏差与方差总结(02)
  2. 古月居_ROS核心概念
  3. python爬虫解析js_python爬虫解析js
  4. Python学习笔记之入门基础
  5. cad解除块的快捷命令_CAD中的块能否修改?能!一个命令可快速解决
  6. 工业互联网产业发展现状及未来前景趋势
  7. 485无线通信/数传模块_zigbee模块_RS485转ZigBee_顺舟智能
  8. 视频播放器SunPlayer开源啦
  9. 玩机小技巧 | 自定义专属自己的优麒麟任务栏托盘
  10. CAS:169501-65-9,4-arm-PEG-NH2,四臂-PEG-氨基可用于修饰蛋白质