一、上下文区域和游标

Oracle服务器分配一个称为上下文区域的私有内存区域来存储由SQL语句处理的数据。 每个上下文区域(因此每个SQL语句)都有一个与其关联的游标。您可以将游标视为上下文区域的标签,或者将其作为指向上下文区域的指针。 事实上,一个游标就是这两个项目。

二、隐式和显式游标

有两种类型的游标:
•隐式游标:由Oracle自动为所有SQL DML语句(INSERT,UPDATE,DELETE和MERGE)以及仅返回一行的SELECT语句定义。
•显式游标:由程序员为返回多行的查询声明。 您可以使用显式游标来命名上下文区域并访问其存储的数据。

三、隐式游标的限制

EMPLOYEES表中有多行:

DECLAREv_salary employees.salary%TYPE;
BEGINSELECT salary INTO v_salaryFROM employees;DBMS_OUTPUT.PUT_LINE(' Salary is : '||v_salary);
END;

ORA-01422: exact fetch returns more than requested number of rows

四、显式游标

使用显式游标,您可以从数据库表中检索多行,为检索到的每行提供一个指针,并且一次处理一行。 以下是使用显式游标的一些原因:
•这是PL / SQL从表中检索多行的唯一方法。
•每行由一个单独的程序语句提取,使程序员可以更好地控制行的处理。

(1)显式游标的例子

以下示例使用明确的游标来获取亚洲国家的国家名称和国定假日。

DECLARECURSOR wf_holiday_cursor IS   --定义游标SELECT country_name, national_holiday_dateFROM wf_countries where region_id IN(30,34,35);v_country_name wf_countries.country_name%TYPE;v_holiday wf_countries.national_holiday_date%TYPE;
BEGINOPEN wf_holiday_cursor; --打开游标LOOPFETCH wf_holiday_cursor INTO v_country_name, v_holiday;  --提取游标一行EXIT WHEN wf_holiday_cursor%NOTFOUND;DBMS_OUTPUT.PUT_LINE(v_country_name||' '||v_holiday);END LOOP;   CLOSE wf_holiday_cursor;  --关闭游标
END;

(2)显式游标操作

由多行查询返回的行集称为活动集,并存储在上下文区域中。 它的大小是符合您的搜索条件的行数。

将上下文区域(由光标命名)看作一个框,并将活动集作为框的内容。 为了获得数据,您必须打开盒子并逐个从盒子中取出每一行。 完成后,您必须关闭该框。

(3)控制显式游标

(4)声明和控制显式游标

五、使用显式游标的步骤

您首先声明一个游标,然后使用OPEN,FETCH和CLOSE语句来控制游标。

1.在声明部分中声明游标。
2.打开光标。
3.从活动集中取出每行,直到该框为空。

4.关闭光标。

OPEN语句执行与游标相关的查询,标识结果集并将光标定位在第一行之前。 FETCH语句检索当前行并将光标前进到下一行。 当最后一行被处理完后,CLOSE语句禁用游标。

(1)声明游标的语法

游标的活动集由游标声明中的SELECT语句确定。
句法:

CURSOR cursor_name ISselect_statement;

在语法中:
cursor_name是PL / SQL标识符
select_statement是一个没有INTO子句的SELECT语句

(2)声明游标示例1

声明emp_cursor游标以检索部门中使用department_id为30的员工的employee_id和last_name列。

DECLARECURSOR emp_cursor ISSELECT employee_id, last_name FROM employeesWHERE department_id =30;
...

(3)声明游标示例2

声明dept_cursor游标以检索具有location_id 1700的部门的所有详细信息。您想按department_name的升序序列提取和处理这些行。

DECLARECURSOR dept_cursor ISSELECT * FROM departmentsWHERE location_id = 1700ORDER BY department_name;
...

(4)声明游标示例3

游标声明中的SELECT语句可以包含连接,组函数和子查询。 此示例检索每个至少有两名员工的部门,并给出部门名称和员工人数。

DECLARECURSOR dept_emp_cursor ISSELECT department_name, COUNT(*) AS how_manyFROM departments d, employees eWHERE d.department_id = e.department_idGROUP BY d.department_nameHAVING COUNT(*) > 1;
...

六、声明游标的指南

在声明游标时:
•不要在游标声明中包含INTO子句,因为它稍后出现在FETCH语句中。
•如果需要处理特定顺序的行,则在查询中使用ORDER BY子句。
游标可以是任何有效的SELECT语句,包括连接,子查询等等。

•如果游标声明引用任何PL / SQL变量,则必须在声明游标之前声明这些变量。

(1)打开光标

OPEN语句执行与游标关联的查询,标识活动集并将光标指针定位到第一行。 OPEN语句包含在PL / SQL块的可执行部分中。

DECLARECURSOR emp_cursor ISSELECT employee_id, last_name FROM employeesWHERE department_id = 30;
...
BEGINOPEN emp_cursor;
...

OPEN语句执行以下操作:
1.为上下文区域分配内存(创建框)
2.在游标声明中执行SELECT语句,将结果返回到活动集(用数据填充框)

3.将指针定位到活动集中的第一行

(2)从光标获取数据

FETCH语句一次从光标中检索一行。 每次提取后,光标前进到活动集中的下一行。 两个变量v_empno和v_lname被声明为保存游标中的取值。

DECLARECURSOR emp_cursor ISSELECT employee_id, last_name FROM employeesWHERE department_id =10;v_empno employees.employee_id%TYPE;v_lname employees.last_name%TYPE;
BEGINOPEN emp_cursor;FETCH emp_cursor INTO v_empno, v_lname;DBMS_OUTPUT.PUT_LINE( v_empno ||' '||v_lname);...
END;

输出:

200 Whalen

Statement processed.

您已成功将光标中的值提取到变量中。 但是,第30部门有6名员工。只有一行被提取。 要获取所有行,您必须使用循环。

DECLARECURSOR emp_cursor ISSELECT employee_id, last_name FROM employeesWHERE department_id =50;v_empno employees.employee_id%TYPE;v_lname employees.last_name%TYPE;
BEGINOPEN emp_cursor;LOOPFETCH emp_cursor INTO v_empno, v_lname;EXIT WHEN emp_cursor%NOTFOUND;DBMS_OUTPUT.PUT_LINE( v_empno ||' '||v_lname);END LOOP; …
END;

输出:

124 Mourgos

141 Rajs
142 Davies
143 Matos
144 Vargas
Statement processed.

(3)从光标获取数据的准则

从光标获取数据时遵循以下准则:

•在FETCH语句的INTO子句中包含与SELECT语句中的列相同数量的变量,并确保数据类型兼容。

•将每个变量与位置上的列进行匹配。

•测试以查看游标是否包含行。 如果提取没有获取值,则在活动集中没有剩余行要处理,并且不记录错误。 最后一行被重新处理。

•您可以使用%NOTFOUND游标属性来测试退出条件。

从光标获取数据示例1

这个例子有什么问题?

DECLARECURSOR emp_cursor ISSELECT employee_id, last_name, salary FROM employeesWHERE department_id =30;v_empno employees.employee_id%TYPE;v_lname employees.last_name%TYPE;v_sal employees.salary%TYPE;
BEGINOPEN emp_cursor;LOOPFETCH emp_cursor INTO v_empno, v_lname;EXIT WHEN emp_cursor%NOTFOUND;DBMS_OUTPUT.PUT_LINE( v_empno ||' '||v_lname);END LOOP; …
END;

从光标获取数据示例2

部门10中只有一名员工。执行此示例时会发生什么?

DECLARECURSOR emp_cursor ISSELECT employee_id, last_name FROM employeesWHERE department_id =10;v_empno employees.employee_id%TYPE;v_lname employees.last_name%TYPE;
BEGINOPEN emp_cursor;LOOPFETCH emp_cursor INTO v_empno, v_lname;DBMS_OUTPUT.PUT_LINE( v_empno ||' '||v_lname);END LOOP; …
END;

(4)关闭光标

CLOSE语句禁用游标,释放上下文区域,并取消定义活动集。 完成FETCH语句处理后关闭游标。 如果需要,您可以稍后重新打开游标。 把CLOSE想象成关闭和清空盒子,所以你不能再取出它的内容。

...LOOPFETCH emp_cursor INTO v_empno, v_lname;EXIT WHEN emp_cursor%NOTFOUND;DBMS_OUTPUT.PUT_LINE( v_empno ||' '||v_lname);END LOOP;
CLOSE emp_cursor;  --关闭游标
END;

关闭游标指南
关闭游标时请遵循以下准则:
•光标只有关闭后才能重新打开。 如果您尝试在游标关闭后从游标读取数据,则会引发INVALID_CURSOR异常。

•如果稍后重新打开游标,将重新执行关联的SELECT语句,以使用来自数据库的最新数据重新填充上下文区域。

七、把它放在一起

以下示例声明并处理游标以获取亚洲国家的国家名称和国家法定节假日。

DECLARECURSOR wf_holiday_cursor ISSELECT country_name, national_holiday_dateFROM wf_countries where region_id IN(30,34,35);v_country_name wf_countries.country_name%TYPE;v_holiday wf_countries.national_holiday_date%TYPE;
BEGINOPEN wf_holiday_cursor;LOOPFETCH wf_holiday_cursor INTO v_country_name, v_holiday;EXIT WHEN wf_holiday_cursor%NOTFOUND;DBMS_OUTPUT.PUT_LINE(v_country_name||' '||v_holiday);END LOOP;CLOSE wf_holiday_cursor;
END;

Oracle入门(十四.10)之显式游标简介相关推荐

  1. Oracle入门(十四.11)之使用显式游标属性

    一.游标和记录 此示例中的游标基于SELECT语句,该语句仅检索每个表行的两列. 如果它检索了六列或七,八,二十个呢? DECLAREv_emp_id employees.employee_id%TY ...

  2. oracle中的cursor属性有哪些,Oracle学习11:游标(cursor)--显式游标隐式游标、游标四个属性、循环遍历...

    1.概述 上文PLSQL学习中提到的知识,可以发现,基本都可以通过Java等语言实现,而为了实现程序的可移植性,实际开发工作中我们也是如此做的. 那么PLSQL的重点是什么呢?接下来我们来介绍游标cu ...

  3. Oracle 11g Release 1 (11.1) 游标——显式游标

    http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/static.htm#CIHCAHJA 本文内容 声明一个游标 打开一个游标 用游标获取一个 ...

  4. Oracle显式游标和隐式游标

    游标的概念: 游标是SQL的一个内存工作区,由系统或用户以变量的形式定义.游标的作用就是用于临时存储从数据库中提取的数据块.在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理,最后将处 ...

  5. oracle显性游标,Oracle高级显式游标的使用

    1.参数化的游标作用:多次打开相同的游标,返回不同的结果集.游标声明部分的形参必须与OPEN语句中提供的实参相对应(数量与数据类型). 例1: DECLARE v_empno emp1.empno%T ...

  6. 【Oracle】PL/SQL 显式游标、隐式游标、动态游标

    在PL/SQL块中执行SELECT.INSERT.DELETE和UPDATE语句时,Oracle会在内存中为其分配上下文区(Context Area),即缓冲区.游标是指向该区的一个指针,或是命名一个 ...

  7. Oracle 游标遍历 显式游标 静态游标 OPEN v_cur(); WHILE v_cur%FOUND LOOP; LOOP FETCH v_cur INTO v_row

    -- Created on 2018/11/6 by YXQ  --显示游标 & 静态游标的处理 declare      --定义(游标一个可以遍历的结果集)      --声明cursor ...

  8. Oracle隐式游标和显式游标

    游标是什么?就是在内存开辟的一块临时存储空间. 1.Oracle隐式游标 1.1Oracle有常用的哪些隐式游标 1.2 Oracle隐式游标演示 -- 隐式游标 (使用的表为Oracle默认自带的e ...

  9. oracle 游标内存自动释放,详解Oracle隐式游标和显式游标

    游标是什么?就是在内存开辟的一块临时存储空间. 1.Oracle隐式游标 1.1Oracle有常用的哪些隐式游标 1.2 Oracle隐式游标演示 -- 隐式游标 (使用的表为Oracle默认自带的e ...

最新文章

  1. ansys怎么合并体_亚马逊合并拆分变体实操(干货)-合并
  2. Kubernetes(7) Service Network (advanced)
  3. python装饰器作用-python装饰器有什么用
  4. boost::minimum_degree_ordering用法的测试程序
  5. 意想不到的JavaScript(每日一题1)
  6. VB常用内部函数大全一览表(建议收藏)
  7. server sql top速度变慢解决方案_SQL Server数据库查询速度慢的原因和解决方法
  8. 人工智障学习笔记——机器学习(5)朴素贝叶斯
  9. Oralce的内存结构
  10. 机器学习中的算法:决策树模型组合之GBDT(Gradient Boost Decision Tree)
  11. 20届美团提前批面经
  12. 华为自带计算机怎么算平方立方,智能家庭中心:华为荣耀立方体验评测
  13. typedef用法总结
  14. 【转载】堆排序算法(图解详细流程)
  15. 搜狗收录提交方法搜狗收录方法
  16. 算法基础-顺序统计量
  17. matlab信道容量函数,一般信道容量迭代算法1
  18. clickhouse集群容器化搭建
  19. PS、Excel快捷键桌面壁纸
  20. 运载火箭飞行控制系统设计

热门文章

  1. 关于前端性能优化问题,认识网页加载过程和防抖节流
  2. [JavaWeb-MySQL]多表关系介绍
  3. [Java基础]字节流读数据
  4. python中开关_pyq中的开关按钮
  5. 数据结构---排序算法的总结
  6. 微软100题第20题
  7. P4551 最长异或路径
  8. 牛客题霸 [ 换钱的最少货币数] C++题解/答案
  9. CF788789(div1div2)
  10. P2324 [SCOI2005]骑士精神(迭代加深搜索,dfs)