Oracle PL/SQL 游标
在PL/SQL块中执行SELECT、INSERT、DELETE和UPDATE语句时,ORACLE会在内存中为其分配上下文区(Context Area),即缓冲区。游标是指向该区的一个指针,或是命名一个工作区(Work Area),或是一种结构化数据类型。
在每个用户会话中,可以同时打开多个游标,其数量由数据库初始化参数文件中的OPEN_CURSORS参数定义。
对于不同的 SQL 语句,游标的使用情况不同:
SQL语句 |
游标 |
非查询语句 |
隐式的 |
结果是单行的查询语句 |
隐式的或显示的 |
结果是多行的查询语句 |
显示的 |
处理显式游标
例:
DECLARE
CURSOR c4(dept_id NUMBER, j_id VARCHAR2) --1、声明游标,有参数没有返回值
IS
SELECT first_name f_name, hire_date FROM employees
WHERE department_id = dept_id AND job_id = j_id; --基于游标定义记录变量,比声明记录类型变量要方便,不容易出错
v_emp_record c4%ROWTYPE;
BEGIN
OPEN c4(90, 'AD_VP'); --2、打开游标,传递参数值
LOOP
FETCH c4 INTO v_emp_record; --3、提取游标fetch into
IF c4%FOUND THEN
DBMS_OUTPUT.PUT_LINE(v_emp_record.f_name||'的雇佣日期是'
||v_emp_record.hire_date);
ELSE
DBMS_OUTPUT.PUT_LINE('已经处理完结果集了');
EXIT;
END IF;
END LOOP;
CLOSE c4; --4、关闭游标
END;
退出LOOP或者用:
EXIT WHEN c4%NOTFOUND;
游标属性:
Cursor_name%FOUND 布尔型属性,当最近一次提取游标操作FETCH成功则为 TRUE,否则为FALSE;
Cursor_name%NOTFOUND 布尔型属性,与%FOUND相反;——注意区别于DO_DATA_FOUND(select into抛出异常)
Cursor_name%ISOPEN 布尔型属性,当游标已打开时返回 TRUE;
Cursor_name
%
ROWCOUNT 数字型属性,返回已从游标中读取的记录数。
游标的for循环
PL/SQL语言提供了游标FOR循环语句,自动执行游标的OPEN、FETCH、CLOSE语句和循环语句的功能;
- 当进入循环时,游标FOR循环语句自动打开游标,并提取第一行游标数据;
- 当程序处理完当前所提取的数据而进入下一次循环时,游标FOR循环语句自动提取下一行数据供程序处理;
- 当提取完结果集合中的所有数据行后结束循环,并自动关闭游标。
格式:
FOR
index_variable
IN
cursor_name
[
(value[, value
]
…)] LOOP
--
游标数据处理代码
END
LOOP;
其中:
index_variable为游标FOR 循环语句隐含声明的索引变量,该变量为记录变量,其结构与游标查询语句返回的结构集合的结构相同。在程序中可以通过引用该索引记录变量元素来读取所提取的游标数据,index_variable中各元素的名称与游标查询语句选择列表中所制定的列名相同。如果在游标查询语句的选择列表中存在计算列,则必须为这些计算列指定别名后才能通过游标FOR 循环语句中的索引变量来访问这些列数据。
例:
DECLARE
CURSOR c_cursor(dept_no NUMBER DEFAULT 10)
IS
SELECT department_name, location_id FROM departments WHERE department_id <= dept_no;
BEGIN
--当dept_no参数值为30
FOR c1_rec IN c_cursor(30) LOOP
DBMS_OUTPUT.PUT_LINE(c1_rec.department_name||'---'||c1_rec.location_id);
END LOOP; --使用默认的dept_no参数值10
FOR c1_rec IN c_cursor LOOP
DBMS_OUTPUT.PUT_LINE(c1_rec.department_name||'---'||c1_rec.location_id);
END LOOP;
END;
或者可以
在游标
FOR
循环语句中使用子查询
BEGIN
FOR c1_rec IN(SELECT department_name, location_id FROM departments) LOOP
DBMS_OUTPUT.PUT_LINE(c1_rec.department_name||'---'||c1_rec.location_id);
END LOOP;
END;
处理隐式游标
显式游标主要是用于对查询语句的处理,尤其是在查询结果为多条记录的情况下;
而对于非查询语句,如修改、删除操作,则由ORACLE 系统自动地为这些操作设置游标并创建其工作区,隐式游标的名字为SQL,这是由ORACLE 系统定义的。
对于隐式游标的操作,如定义、打开、取值及关闭操作,都由ORACLE 系统自动地完成,无需用户进行处理。用户只能通过隐式游标的相关属性,来完成相应的操作。在隐式游标的工作区中,所存放的数据是与用户自定义的显示游标无关的、最新处理的一条SQL 语句所包含的数据。
格式调用为:
SQL%
DECLARE
v_rows NUMBER;
BEGIN
--更新数据
UPDATE employees SET salary = 30000
WHERE department_id = 90 AND job_id = 'AD_VP';
--获取默认游标的属性值
v_rows := SQL%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE('更新了'||v_rows||'个雇员的工资'); --删除指定雇员;如果部门中没有雇员,则删除部门
DELETE FROM employees WHERE department_id=v_deptno;
IF SQL%NOTFOUND THEN
DELETE FROM departments WHERE department_id=v_deptno;
END IF;
END;
更新或删除当前游标数据
游标查询语句中必须使用FOR UPDATE选项,以便在打开游标时锁定游标结果集合在表中对应数据行的所有列和部分列。
如果另一个会话已对活动集中的行加了锁,那么SELECT FOR UPDATE操作一直等待到其它的会话释放这些锁后才继续自己的操作;对于这种情况,当加上NOWAIT子句时,如果这些行真的被另一个会话锁定,则OPEN立即返回并给出:
ORA-0054 :resource busy and acquire with nowait specified.
DECLARE
V_deptno employees.department_id%TYPE :=&p_deptno;
CURSOR emp_cursor
IS
SELECT employees.employee_id, employees.salary
FROM employees WHERE employees.department_id=v_deptno
FOR UPDATE NOWAIT; --1、for update
BEGIN
FOR emp_record IN emp_cursor LOOP
IF emp_record.salary < 1500 THEN
UPDATE employees SET salary=1500
WHERE CURRENT OF emp_cursor; --2、WHERE CURRENT OF cursor_name子句
END IF;
END LOOP;
END;
动态游标
与游标一样,动态游标(游标变量)也是一个指向多行查询结果集合中当前数据行的指针。但与游标不同的是,游标变量是动态的,而游标是静态的。
游标只能与指定的查询相连,即固定指向一个查询的内存处理区域,而游标变量则可与不同的查询语句相连,它可以指向不同查询语句的内存处理区域(但不能同时指向多个内存处理区域,在某一时刻只能与一个查询语句相连),只要这些查询语句的返回类型兼容即可。
DECLARE
--定义一个游标数据类型
TYPE emp_cursor_type IS REF CURSOR;
--声明一个游标变量
c1 EMP_CURSOR_TYPE;
--声明两个记录变量
v_emp_record employees%ROWTYPE;
v_reg_record regions%ROWTYPE; BEGIN
OPEN c1 FOR SELECT * FROM employees WHERE department_id = 20;
LOOP
FETCH c1 INTO v_emp_record;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_emp_record.first_name||'的雇佣日期是'
||v_emp_record.hire_date);
END LOOP;
--将同一个游标变量对应到另一个SELECT语句
OPEN c1 FOR SELECT * FROM regions WHERE region_id IN(1,2);
LOOP
FETCH c1 INTO v_reg_record;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_reg_record.region_id||'表示'
||v_reg_record.region_name);
END LOOP;
CLOSE c1;
END;
Oracle PL/SQL 游标的更多相关文章
- Oracle PL/SQL游标
游标的提出: SQL是面向集合的,其结果一般是集合量(多条记录),而PL/SQL的变量一本是标量,其一组变量异常一直只能存放一条记录.所以仅仅使用变量并不能完全满足SQL语句向应用程序输出数据的要求. ...
- [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到)
原文:[推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) [推荐]ORACLE PL/SQL编程之四: 把游标说透(不怕做不到,只怕想不到) 继上两篇:ORACLE PL ...
- ORACLE PL/SQL编程详解
ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...
- [强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!)
原文:[强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!) [强烈推荐]ORACLE PL/SQL编程详解之七: 程序包的创建与应用(聪明在于学习,天 ...
- ORACLE PL/SQL编程之八:把触发器说透
原文:ORACLE PL/SQL编程之八:把触发器说透 ORACLE PL/SQL编程之八: 把触发器说透 大家一定要评论呀,感谢!光发表就花了我将近一个下午. 本篇主要内容如下: 8.1 触发器类型 ...
- [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)
原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/S ...
- [推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)
原文:[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆) [推荐]ORACLE PL/SQL编程详解之三: PL/SQL流程控制语句(不给规则,不成方圆) ...
- 【强烈强烈推荐】《ORACLE PL/SQL编程详解》全原创(共八篇)--系列文章导航
原文:[强烈强烈推荐]<ORACLE PL/SQL编程详解>全原创(共八篇)--系列文章导航 <ORACLE PL/SQL编程详解> 系列文章目录导航 ——通过知识共享树立个人 ...
- [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)
原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下 ...
随机推荐
- Expression Language
EL找不到属性会返回"" page –- request --- session --- application ------------------------------- ...
- selenium css(转)
如果button上有class属性的,如: <button id="ext-eng=1026" class="x-right-button"...&g ...
- jQuery入门第三
jQuery入门第三 1.HTML 2.CSS 衣服 3.javascript 可以动的人 4.DOM 编程 对html文档的节点操作 5.jQuery 对 javascript的封装 简练的语法 复 ...
- JAVA并发,后台线程
package com.xt.thinks21_2; import java.util.concurrent.TimeUnit; /** * 后台线程测试 * * @author Administra ...
- CCNA实验(6) -- VLAN & SPT
交换机的作用主要有两个:1.维护CAM(ContextAddress Memory)表,该表是MAC地址和交换机端口的映射表2.根据CAM进行数据帧的转发 交换机对数据帧的处理有三种:1.Forwar ...
- cocos2dx CCTextFieldTTF
CCTextFieldTTF是一个提供文本输入的控件. 先上个简单的例子 CCSize size = __winSize; CCTextFieldTTF* textEdit = CCTextField ...
- JAVA异常设计原则
异常是面向对象语言非常重要的一个特性,良好的异常设计对程序的可扩展性.可维护性.健壮性都起到至关重要. JAVA根据用处的不同,定义了两类异常 * Checked Exception: Exc ...
- Cocos2d-x:环境配置小节
一.准备 须要下载下面内容. 1. vs2010 下载地址:http://download.microsoft.com/download/1/4/3/143B7583-6225-474F-88D5-5 ...
- hdu 4873 ZCC Loves Intersection(大数+概率)
pid=4873" target="_blank" style="">题目链接:hdu 4873 ZCC Loves Intersection ...
- zoj 3197 Google Book
这道题告诉我想法正确是多么重要,先是我自己想的时候没考虑到最后的页码作为循环的终止,我一直以区间个数来终止循环,这是多么愚蠢啊!然后,我看了别人的代码,但是很不幸超时了! 我自己wa的代码,我感觉很正 ...